{"componentChunkName":"component---src-templates-post-js","path":"/blog/workpad-part-6","webpackCompilationHash":"97000b66fda8dd565841","result":{"data":{"site":{"siteMetadata":{"keywords":["blog","ubug","tech blog","技术博客","playground"]}},"mdx":{"fields":{"title":"🌋 WebIDE 的开发记录其六（LSP 支持）","tips":[],"categories":["webide"],"datetime":"2020-02-03 20:01:25","noFooter":false,"description":"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第六篇文章，谈谈怎么在 monaco-editor 上添加语言服务支持 LSP 的。","plainTextDescription":"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第六篇文章，谈谈怎么在 monaco-editor 上添加语言服务支持 LSP 的。\n","author":"Ubug","banner":{"childImageSharp":{"fluid":{"tracedSVG":"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='400'%20height='291'%3e%3cpath%20d='M0%20147v137h313v-35c1-39%200-40-2-40l-1-2c0-2%201-3%202-3l1-15%201-10v-1l-1-7v-6h78v119h10V9H76v20h-5c-4%200-5%200-4-1h-1c-2%201-4%201-4-2l-1-1v3c1%201-4%201-10%201l-8-1c2%200%203-1%203-3s0-2-9-2-9%200-9%202c-1%203%200%203%205%203l-9%201c-14%200-15%200-14-2v-2l-1-5C9%208%2010%209%205%209H0v138M284%2020l-1%201c-2%200-2%202-2%2012v12h28v-6a163%20163%200%20000-13v-7h-13l-12%201m-137%203l2%202%201-1h1c1%201%2050%201%2050-1%200-1-4-2-27-2-26%200-27%200-27%202m171%2014l37%201%2036-1-36-1-37%201M9%2071v3h67v-6H9v3m108%2044v2c-1%202%201%202%2020%202a94%2094%200%200021-1l1-1a2801%202801%200%2000-42-1m-24%2011v3H76v3c0%203%200%203%203%203h103l99%201v-7H94v-3l-1-2v2m244%2015l16%201h-16l-16%201a830%20830%200%200016-2m-218%203l-2%201c0%201%204%202%2017%202%2016%200%2017%200%2017-2l-15-1h-17m-31%2010c-11%200-12%200-12%202s1%202%2096%202h98c1%200%202-1%202-3v-2h-86l-98%201'%20fill='%23573ede'%20fill-rule='evenodd'/%3e%3c/svg%3e","aspectRatio":1.3726273726273726,"src":"/static/bb64a05fbbe7c7a1e8fb20d74f544712/9679e/WorkPad-demo.png","srcSet":"/static/bb64a05fbbe7c7a1e8fb20d74f544712/82675/WorkPad-demo.png 500w,\n/static/bb64a05fbbe7c7a1e8fb20d74f544712/fef60/WorkPad-demo.png 1000w,\n/static/bb64a05fbbe7c7a1e8fb20d74f544712/9679e/WorkPad-demo.png 1374w","srcWebp":"/static/bb64a05fbbe7c7a1e8fb20d74f544712/3c76f/WorkPad-demo.webp","srcSetWebp":"/static/bb64a05fbbe7c7a1e8fb20d74f544712/7fe04/WorkPad-demo.webp 500w,\n/static/bb64a05fbbe7c7a1e8fb20d74f544712/d619e/WorkPad-demo.webp 1000w,\n/static/bb64a05fbbe7c7a1e8fb20d74f544712/3c76f/WorkPad-demo.webp 1374w","sizes":"(max-width: 1374px) 100vw, 1374px"}}},"bannerCredit":null,"slug":"/blog/workpad-part-6","tags":["思考","整理","WorkPad","WebIDE","云开发","LSP"]},"headings":[{"value":"一、背景","depth":2},{"value":"二、内置的方案","depth":2},{"value":"1. addExtraLib 添加声明文件","depth":3},{"value":"2. setEagerModelSync 多文件提示","depth":3},{"value":"三、 转到定义、查看引用 功能的实现","depth":2},{"value":"四、LSP 是什么？","depth":2},{"value":"五、服务端集成 LSP","depth":2},{"value":"1. 架构","depth":3},{"value":"2. 服务端和客户端的数据通道 ws","depth":3},{"value":"3. rpc 协议 和 ws socket","depth":3},{"value":"4. 语言服务进程","depth":3},{"value":"5. 将 ws jsonrpc 和 语言服务 粘在一起","depth":3},{"value":"六、客户端集成 LSP","depth":2},{"value":"1. 绑定 monaco","depth":3},{"value":"2. 创建 ws 承载数据传输","depth":3},{"value":"3. 在 ws 上搭建 jsonrpc 数据通道","depth":3},{"value":"4. 语言客户端","depth":3},{"value":"5. 启动","depth":3},{"value":"七、结束","depth":2},{"value":"八、更多","depth":2}],"body":"const _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsx mdx */\n\nconst _frontmatter = {\n  \"slug\": \"workpad-part-6\",\n  \"title\": \"🌋 WebIDE 的开发记录其六（LSP 支持）\",\n  \"date\": \"2020-02-03 20:01:25\",\n  \"author\": \"Ubug\",\n  \"description\": \"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第六篇文章，谈谈怎么在 monaco-editor 上添加语言服务支持 LSP 的。\",\n  \"series\": \"WebIDE 的开发记录\",\n  \"categories\": [\"webide\"],\n  \"tags\": [\"思考\", \"整理\", \"WorkPad\", \"WebIDE\", \"云开发\", \"LSP\"],\n  \"banner\": \"./WorkPad-demo.png\"\n};\nconst makeShortcode = name => function MDXDefaultShortcode(props) {\n  console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n  return mdx(\"div\", props);\n};\nconst WithFigcaption = makeShortcode(\"WithFigcaption\");\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n      components\n    } = _ref,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h2\", null, \"\\u4E00\\u3001\\u80CC\\u666F\"), mdx(\"p\", null, \"\\u4E00\\u4E2A IDE \\u548C\\u7F16\\u8F91\\u5668\\u5F88\\u660E\\u663E\\u7684\\u4F7F\\u7528\\u533A\\u522B\\u5C31\\u662F \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"go to definition\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"go to references\"), \" \\u7684\\u5B9A\\u4E49\\u548C\\u5F15\\u7528\\u8DF3\\u8F6C\\uFF0C\\u7F3A\\u5C11\\u4E86\\u8FD9\\u4E2A\\u529F\\u80FD\\uFF0C\\u90A3\\u4E48\\u548C\\u6700\\u7B80\\u5355\\u7684\\u8BB0\\u4E8B\\u672C\\u6709\\u4EC0\\u4E48\\u533A\\u522B\\u3002\"), mdx(\"p\", null, \"\\u5982\\u679C\\u7A0D\\u5FAE\\u6DF1\\u5165\\u4E86\\u89E3 monaco-editor \\u4E4B\\u540E\\uFF0C\\u4E0D\\u6EE1\\u8DB3\\u53EA\\u662F\\u7B80\\u5355\\u7684\\u7F16\\u8F91\\uFF0C\\u60F3\\u8981\\u81EA\\u52A8\\u63D0\\u793A\\u3001\\u81EA\\u52A8\\u8865\\u5168\\u7684\\u529F\\u80FD\\uFF0C\\u6BD4\\u5982 VSCode \\u4E2D\\u5F15\\u5165\\u6A21\\u5757\\u6587\\u4EF6\\u4E4B\\u540E\\uFF0C\\u53EF\\u4EE5\\u5728\\u5F53\\u524D\\u6587\\u4EF6\\u4E2D\\u770B\\u5230\\u53E6\\u4E00\\u4E2A\\u6587\\u4EF6\\u4E2D\\u7684\\u6570\\u636E\\u5F15\\u7528\\u3001\\u7C7B\\u578B\\u5B9A\\u4E49\\u3001\\u53C2\\u6570\\u63D0\\u793A\\u7B49\\u3002\"), mdx(\"p\", null, \"\\u5355\\u4ECE\\u8FD9\\u4E2A\\u9700\\u6C42\\u4E0A\\u6765\\u627E\\u89E3\\u51B3\\u65B9\\u6848\\u7684\\u8BDD\\uFF0C\\u4E00\\u756A\\u641C\\u7D22\\u4E4B\\u540E\\u53D1\\u73B0 monaco-editor \\u5728\\u4E00\\u5B9A\\u7A0B\\u5EA6\\u4E0A\\u662F\\u80FD\\u591F\\u652F\\u6301\\u7684\\u3002\"), mdx(\"p\", null, \"\\u5148\\u770B\\u7ED3\\u679C\\uFF1A\"), mdx(\"div\", {\n    style: {\n      display: 'flex',\n      justifyContent: 'center'\n    }\n  }, mdx(WithFigcaption, {\n    title: \"\\u5728\\u7EBF IDE \\u9879\\u76EE\\u4E2D\\u96C6\\u6210 LSP \\u6548\\u679C\",\n    mdxType: \"WithFigcaption\"\n  }, mdx(\"video\", {\n    autoPlay: true,\n    loop: true,\n    controls: true,\n    style: {\n      maxWidth: '100%'\n    }\n  }, mdx(\"source\", {\n    src: \"https://fdb.ubug.io/storybook-videos/lsp-demo.mp4\",\n    type: \"video/mp4\"\n  })))), mdx(\"h2\", null, \"\\u4E8C\\u3001\\u5185\\u7F6E\\u7684\\u65B9\\u6848\"), mdx(\"h3\", null, \"1. addExtraLib \\u6DFB\\u52A0\\u58F0\\u660E\\u6587\\u4EF6\"), mdx(\"p\", null, \"\\u6BD4\\u5982\\u6DFB\\u52A0\\u81EA\\u5B9A\\u4E49\\u7684\\u7C7B\\u578B\\u6587\\u4EF6\\uFF08\\u53EF\\u4EE5\\u662F d.ts \\u6587\\u4EF6\\uFF09\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"//  typescript \\u89E3\\u6790\\u914D\\u7F6E\\nmonaco.languages.typescript.typescriptDefaults.setCompilerOptions({\\n  target: monaco.languages.typescript.ScriptTarget.ES2016,\\n  allowNonTsExtensions: true,\\n  moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,\\n  module: monaco.languages.typescript.ModuleKind.CommonJS,\\n  noEmit: true,\\n  typeRoots: [\\\"node_modules/@types\\\"]\\n});\\n\\n// \\u6DFB\\u52A0\\u989D\\u5916\\u7684\\u5E93\\u652F\\u6301\\nmonaco.languages.typescript.typescriptDefaults.addExtraLib(\\n  `export declare function next() : string`,\\n  'node_modules/@types/external/index.d.ts'\\n);\\n\\n// \\u6253\\u5F00\\u8BED\\u6CD5\\u68C0\\u67E5\\u529F\\u80FD\\nmonaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({\\n  noSemanticValidation: false,\\n  noSyntaxValidation: false\\n})\\n\\nvar jsCode = `import * as x from \\\"external\\\"\\n    const tt : string = x.dnext();`;\\n\\n// model \\u4E2D uri \\u5C5E\\u6027 \\u6DFB\\u52A0 file \\u5F00\\u5934\\uFF0C\\u5373\\u53EF\\u5728\\u7F16\\u8F91\\u5668\\u4E2D\\u770B\\u5230\\u5BF9\\u5E94\\u7684\\u4EE3\\u7801\\u63D0\\u793A\\u4E86\\nmonaco.editor.create(document.getElementById(\\\"container\\\"), {\\n  model: monaco.editor.createModel(jsCode,\\\"typescript\\\",new monaco.Uri(\\\"file:///main.ts\\\")), \\n});\\n\")), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u65B9\\u6848\\u5B9E\\u73B0\\u8D77\\u6765\\u5F88\\u7B80\\u5355\\uFF0C\\u4F46\\u662F\\u5E94\\u7528\\u573A\\u666F\\u5E94\\u8BE5\\u662F\\u8003\\u8651\\u5BF9\\u4E8E\\u4E00\\u4E9B\\u7279\\u5B9A\\u9886\\u57DF\\u7684\\u8F93\\u5165\\u63D0\\u4F9B\\u652F\\u6301\\u7684\\uFF0C\\u6BD4\\u5982\\u67D0\\u4E2A SDK \\u7684\\u6D4B\\u8BD5\\u754C\\u9762\\uFF0C\\u5305\\u542B\\u67D0\\u4E9B\\u63D0\\u793A\\u652F\\u6301\\u7684\\u7B80\\u5355\\u7F16\\u8F91\\u5668\\u7B49\\u3002\"), mdx(\"p\", null, \"\\u6211\\u4EEC\\u7684\\u76EE\\u6807\\u662F IDE\\uFF0C\\u4E0D\\u4EC5\\u5305\\u542B\\u56FA\\u5B9A\\u7684 lib \\u652F\\u6301\\uFF0C\\u8FD8\\u9700\\u8981\\u591A\\u6587\\u4EF6\\u3001\\u6587\\u4EF6\\u6A21\\u5757\\u7684\\u4E92\\u76F8\\u5F15\\u7528\\uFF0C\\u6BD4\\u5982 import \\u8BED\\u53E5\\u5F15\\u5165\\u7684\\u6A21\\u5757\\u3002\\u8FD9\\u4E2A\\u65B9\\u6CD5\\u53EF\\u80FD\\u53EF\\u4EE5\\u5B9E\\u73B0\\uFF0C\\u4F46\\u662F\\u5B9E\\u73B0\\u8D77\\u6765\\u8FD8\\u662F\\u5F88\\u590D\\u6742\\u7684\\uFF0C\\u6BD5\\u7ADF\\u4E0D\\u53EF\\u80FD\\u68C0\\u6D4B\\u54EA\\u4E9B import \\u6216\\u8005 require \\u7136\\u540E\\u518D\\u53BB addExtraLib\\u3002\"), mdx(\"h3\", null, \"2. setEagerModelSync \\u591A\\u6587\\u4EF6\\u63D0\\u793A\"), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u65B9\\u5F0F\\u66F4\\u52A0\\u63A5\\u8FD1\\u6211\\u4EEC\\u7684\\u9700\\u6C42\\uFF0C\\u4F7F\\u7528\\u5355\\u4F8B\\u7684 editor\\uFF0C\\u52A0\\u8F7D\\u5168\\u90E8\\u6587\\u4EF6\\u7684 model \\u5B9E\\u4F8B\\uFF0C\\u7136\\u540E setEagerModelSync \\u6765\\u542F\\u7528\\u8DE8 model \\u540C\\u6B65\\u529F\\u80FD\\uFF08\\u8D2A\\u5A6A\\u6A21\\u578B\\u540C\\u6B65\\uFF1F\\uFF09\\u3002\"), mdx(\"p\", null, \"\\u5355\\u4F8B editor \\u7684\\u5B9E\\u73B0\\u6211\\u4EEC\\u4E4B\\u524D\\u5728 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/blog/workpad-part-3\"\n  }, \"\\uD83C\\uDF0B WebIDE \\u7684\\u5F00\\u53D1\\u8BB0\\u5F55\\u5176\\u4E09\\uFF08editor \\u96C6\\u6210\\uFF09\"), \" \\u4E2D\\u5DF2\\u7ECF\\u8BB2\\u8FC7\\u4E86\\uFF0C\\u7528 model \\u548C viewState \\u7684\\u5207\\u6362\\u6765\\u652F\\u6301\\u591A\\u6587\\u4EF6\\uFF0C\\u8FD9\\u91CC\\u6211\\u4EEC\\u53EA\\u9700\\u8981 setEagerModelSync \\u5C31\\u80FD\\u6EE1\\u8DB3\\u8981\\u6C42\\u4E86\\u3002\"), mdx(\"p\", null, \"\\u5148\\u6D4B\\u8BD5\\u4E00\\u4E0B\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// !!!!! \\u8BBE\\u7F6E\\u914D\\u7F6E(js \\u548C ts \\u90FD\\u8BBE\\u7F6E\\u4E00\\u4E0B)\\nmonaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)\\nmonaco.languages.typescript.javascriptDefaults.setEagerModelSync(true)\\n\\n// \\u9ED8\\u8BA4\\u6587\\u4EF6\\u7684 model\\nconst fileModel_1 = monaco.editor.createModel(\\n  `import * as x from \\\"./test\\\"\\n    const tt : string = x.dnext();`,\\n  \\\"typescript\\\",\\n  new monaco.Uri(\\\"file:///main.ts\\\"),\\n)\\n\\n// \\u88AB\\u5F15\\u7528\\u6587\\u4EF6\\u7684 model\\nconst fileModel_2 = monaco.editor.createModel(\\n  \\\"export const dnext = () => { return \\\\\\\"Hello World!\\\\\\\"; }\\\",\\n  \\\"typescript\\\",\\n  new monaco.Uri(\\\"file:///test.ts\\\"), // \\u4E00\\u5B9A\\u6CE8\\u610F file \\u548C\\u76F8\\u5BF9\\u8DEF\\u5F84\\n)\\n\\n// \\u521B\\u5EFA\\u5355\\u4F8B\\u7684\\u7F16\\u8F91\\u5668\\nmonaco.editor.create(document.getElementById(\\\"container\\\"), {\\n  model: fileModel_1,\\n});\\n\")), mdx(\"p\", null, \"\\u4E0D\\u51FA\\u610F\\u5916\\u7684\\u8BDD\\u5E94\\u8BE5\\u662F\\u53EF\\u4EE5\\u63D0\\u4F9B\\u591A\\u6587\\u4EF6\\u7684\\u4EE3\\u7801\\u63D0\\u793A\\u4E86\\uFF0C\\u53EF\\u662F~~~\"), mdx(\"p\", null, \"\\u5982\\u679C\\u4E00\\u4E2A\\u9879\\u76EE\\u4E2D\\u5C31\\u53EA\\u6709\\u51E0\\u4E2A\\u6587\\u4EF6\\u7684\\u8BDD\\uFF0C\\u6548\\u679C\\u8FD8\\u53EF\\u4EE5\\uFF0C\\u4F46\\u662F\\u5982\\u679C\\u9879\\u76EE\\u4E2D\\u5305\\u542B\\u51E0\\u5341\\u4E2A\\u6587\\u4EF6\\u5462\\uFF1F\\u9700\\u8981\\u5168\\u90E8\\u5427\\u5185\\u5BB9\\u83B7\\u53D6\\uFF0C\\u7136\\u540E\\u521B\\u5EFA model \\u624D\\u80FD\\u88AB\\u89E3\\u6790\\uFF0C\\u63D0\\u4F9B\\u667A\\u80FD\\u63D0\\u793A\\uFF0C\\u800C\\u4E14\\u597D\\u50CF\\u53EA\\u6709 js\\u3001ts\\u3001html \\u4E4B\\u7C7B\\u7684\\u8BED\\u8A00\\uFF0C\\u5B98\\u65B9 worker \\u624D\\u80FD\\u652F\\u6301\\u3002\\u8FD9\\u4E2A\\u597D\\u50CF\\u6709\\u70B9\\u4E0D\\u592A\\u597D~~~\"), mdx(\"p\", null, \"\\u4E0D\\u8FC7\\u81F3\\u5C11\\u8FD9\\u662F\\u4E00\\u4E2A\\u5F88\\u4F4E\\u6210\\u672C\\u7684\\u89E3\\u51B3\\u65B9\\u6848~~\"), mdx(\"h2\", null, \"\\u4E09\\u3001 \\u8F6C\\u5230\\u5B9A\\u4E49\\u3001\\u67E5\\u770B\\u5F15\\u7528 \\u529F\\u80FD\\u7684\\u5B9E\\u73B0\"), mdx(\"p\", null, \"\\u4E0A\\u9762\\u8BF4\\u7684\\u90FD\\u662F\\u4EE3\\u7801\\u63D0\\u793A\\u7684\\u95EE\\u9898\\uFF0C\\u4E5F\\u5C31\\u662F\\u89E3\\u6790\\u7684\\u65F6\\u5019\\u80FD\\u591F\\u77E5\\u9053\\u5F15\\u5165\\u7684\\u7C7B\\u578B\\uFF0C\\u6587\\u4EF6\\u4E4B\\u95F4\\u7684\\u667A\\u80FD\\u63D0\\u793A\\u6548\\u679C\\uFF0C\\u4F46\\u662F\\u5982\\u679C\\u70B9\\u51FB\\u8F6C\\u5230\\u5B9A\\u4E49\\u529F\\u80FD\\uFF0C\\u60F3\\u8981\\u6253\\u5F00\\u5BF9\\u5E94\\u7684\\u6587\\u4EF6\\uFF0C\\u597D\\u50CF\\u4E0D\\u53EF\\u4EE5\\uFF0C\\u6BD5\\u7ADF monaco-editor \\u4E0D\\u77E5\\u9053\\u6211\\u4EEC\\u600E\\u4E48\\u624D\\u80FD\\u6253\\u5F00\\u4E00\\u4E2A\\u6587\\u4EF6\\uFF0C\\u5305\\u62EC\\u8F6C\\u5230\\u5B9A\\u4E49\\u3001\\u67E5\\u770B\\u5B9A\\u4E49\\u3001\\u67E5\\u770B\\u5F15\\u7528\\u3001\\u8F6C\\u5230\\u7C7B\\u578B\\u5B9A\\u4E49\\u7B49\\u3002\"), mdx(\"p\", null, \"monaco-editor \\u63D0\\u4F9B\\u4E86\\u4E00\\u4E2A editorService \\u7684\\u529F\\u80FD\\u53EF\\u4EE5\\u8BA9\\u7528\\u6237\\u81EA\\u5DF1\\u6269\\u5C55\\u4E00\\u4E9B\\u9AD8\\u7EA7\\u529F\\u80FD\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"// \\u672C\\u6765\\u662F\\nlet editorOverrides = {\\n  editorService: {\\n    // openEditor: function () {\\n    //   alert(`open editor called!` + JSON.stringify(arguments));\\n    // },\\n    // resolveEditor: function () {\\n    //   alert(`resolve editor called!` + JSON.stringify(arguments));\\n    // }\\n  }\\n}\\n\\nconst defaultModel = monaco.editor.createModel('', 'plaintext');\\nconst editor = monaco.editor.create(this.el, { model: defaultModel }, editorOverrides);\\n\")), mdx(\"p\", null, \"\\u5176\\u4E2D \\u7B2C\\u4E09\\u4E2A\\u53C2\\u6570 OverrideServices \\u76EE\\u7684\\u662F\\u8986\\u76D6\\u5185\\u7F6E\\u7684\\u4E00\\u4E9B\\u670D\\u52A1\\uFF0C\\u6BD4\\u5982\\u8DF3\\u8F6C\\u5230\\u6216\\u8005\\u5F15\\u7528\\u7B49\\u529F\\u80FD\\uFF0C\\u5728\\u67D0\\u4E9B\\u7248\\u672C\\u4E2D\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/microsoft/monaco-editor/issues/291#issuecomment-450709332\"\n  }, \"\\u53EF\\u80FD\\u4F1A\\u88AB\\u8986\\u76D6\\u5BFC\\u81F4\\u5931\\u6548\"), \"\\uFF0C\\u53EF\\u4EE5\\u901A\\u8FC7\\u76F8\\u5BF9 hack \\u7684\\u65B9\\u5F0F\\u6DFB\\u52A0\\u529F\\u80FD\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"\\nfunction hackOverides(editor: monaco.editor.IStandaloneCodeEditor) {\\n  // @ts-ignore\\n  const services = [...editor._instantiationService._parent._services._entries.values()];\\n  const textModelService = services.find((service) => {\\n    const props = Object.getPrototypeOf(service)\\n    return props && 'createModelReference' in props\\n  });\\n\\n  // @ts-ignore\\n  const codeEditorService = editor._codeEditorService;\\n  codeEditorService.openCodeEditor = (input: { resource: monaco.Uri, options: any }) => {\\n    const { resource, options } = input\\n    const file = resource.path;\\n    const range = options.selection;\\n    // Add code here to open the code editor.\\n\\n    const states = window._novus.models.workspace.state\\n    let path = file.replace(states.config.path, '')\\n\\n    commandsPool.writer.openFile.trigger(path, () => {\\n      window._novus.models.writer.state.currentEditor.setSelection(range);\\n      window._novus.models.writer.state.currentEditor.revealLineInCenter(range.startLineNumber);\\n    });\\n  }\\n\\n\\n  textModelService.createModelReference = async (uri: monaco.Uri) => {\\n\\n    const fileManagerModel = window._novus.models[\\\"fileManager\\\"]\\n\\n    const states = window._novus.models.workspace.state\\n    let fileId = uri.path.replace(states.config.path, '')\\n    let model = modelsHolder.models[fileId];\\n\\n    if (!model) {\\n      let file = await fileManagerModel.actions.queryFile(fileId);\\n      const contentsMap = fileManagerModel.state.contentsMap\\n      const content = contentsMap[fileId];\\n      const language = getLang(`.${fileId.split('.').pop()}`)\\n\\n      if (file) {\\n        await fileManagerModel.actions.fetchFileContent(fileId);\\n        modelsHolder.addModel(file.relative, file.path, content, language);\\n        model = modelsHolder.models[fileId];\\n      }\\n    }\\n\\n    const reference = {\\n      load() {\\n        return Promise.resolve(model.model)\\n      },\\n      // in my case, I have nothing to dispose as I just re-use existing resources\\n      dispose() { },\\n      textEditorModel: model.model\\n    }\\n    return {\\n      object: reference,\\n      dispose() { },\\n    };\\n  };\\n}\\n\\nhackOverides(editor);\\n\")), mdx(\"p\", null, \"\\u8DF3\\u8F6C\\u548C\\u5F15\\u7528\\u67E5\\u770B\\u4E4B\\u540E\\uFF0C\\u667A\\u80FD\\u63D0\\u793A\\u5C31\\u6BD4\\u8F83\\u5B8C\\u6574\\u4E86\"), mdx(\"h2\", null, \"\\u56DB\\u3001LSP \\u662F\\u4EC0\\u4E48\\uFF1F\"), mdx(\"p\", null, \"\\u4E0A\\u9762\\u8BF4\\u4E86 monaco-editor \\u5982\\u679C\\u8981\\u5B8C\\u6574\\u7684\\u4EE3\\u7801\\u63D0\\u793A\\uFF0C\\u9700\\u8981\\u5C06\\u5168\\u90E8\\u4F9D\\u8D56\\u6587\\u4EF6\\u52A0\\u8F7D\\u5230\\u672C\\u5730\\uFF0C\\u8FD9\\u4E2A\\u5BF9\\u4E8E\\u7B80\\u5355\\u9879\\u76EE\\u6216\\u8005\\u56FA\\u5B9A\\u7684\\u6587\\u4EF6\\u53EF\\u4EE5\\u64CD\\u4F5C\\uFF0C\\u4F46\\u662F\\u5BF9\\u4E8E\\u6211\\u4EEC IDE \\u9879\\u76EE\\u6765\\u8BF4\\u662F\\u5F88\\u4E0D\\u73B0\\u5B9E\\u7684\\u3002\"), mdx(\"p\", null, \"\\u5176\\u5B9E\\u7F16\\u8F91\\u5668\\u7684\\u65B9\\u5411\\u91CC\\u9762\\uFF0C\\u6709 LSP(Language Server Protocol) \\u7684\\u6982\\u5FF5:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"The Language Server Protocol (LSP) defines the protocol used between an editor or IDE and a language server that provides language features like auto complete, go to definition, find all references etc. The goal of the Language Server Index Format (LSIF, pronounced like \\\"else if\\\") is to support rich code navigation in development tools or a Web UI without needing a local copy of the source code.\")), mdx(\"p\", null, \"\\u7FFB\\u4E00\\u4E0B\\u5C31\\u662F\\u5B9A\\u4E49\\u4E86\\u4E00\\u4E2A\\u8BED\\u8A00\\u670D\\u52A1\\u548C\\u7F16\\u8F91\\u5668\\u76F4\\u63A5\\u7684\\u534F\\u8BAE\\uFF0C\\u800C\\u8BED\\u8A00\\u670D\\u52A1\\u80FD\\u591F\\u63D0\\u4F9B\\u81EA\\u52A8\\u5B8C\\u6210\\u3001\\u8DF3\\u8F6C\\u5B9A\\u4E49\\u3001\\u5F15\\u7528\\u67E5\\u770B\\u7B49\\u529F\\u80FD\\uFF0C\\u8FD9\\u4E2A\\u529F\\u80FD\\u80FD\\u8BA9\\u8BED\\u8A00\\u7684\\u652F\\u6301\\u80FD\\u529B\\u548C\\u7F16\\u8F91\\u5668\\u5206\\u5F00\\uFF0C\\u6240\\u4EE5\\u7F16\\u8F91\\u5668\\u4E0D\\u518D\\u9700\\u8981\\u6BCF\\u4E2A\\u8BED\\u8A00\\u90FD\\u8981\\u5F00\\u53D1\\u8BED\\u6CD5\\u89E3\\u6790\\u7B49\\u7E41\\u6742\\u7684\\u529F\\u80FD\\uFF0C\\u65B0\\u51FA\\u7684\\u8BED\\u8A00\\u4E5F\\u80FD\\u5F88\\u5FEB\\u7684\\u9002\\u5E94\\u3002\"), mdx(\"p\", null, \"\\u5176\\u4E2D\\u8BED\\u8A00\\u670D\\u52A1\\u5668\\u76EE\\u524D\\u5DF2\\u7ECF\\u6709\\u5F88\\u591A\\u7684\\u5B9E\\u73B0\\u4E86 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://microsoft.github.io/language-server-protocol/implementors/servers/\"\n  }, \"\\u67E5\\u770B\\u5217\\u8868\"), \"\\uFF1A\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Language\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Maintainer\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Repository\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Implementation Language\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  })), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Go\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/golang/tools\"\n  }, \"Go Team\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/golang/tools/tree/master/gopls\"\n  }, \"gopls\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Go\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"http://graphql.org/\"\n  }, \"GraphQL\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"GraphQL community\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/graphql/graphql-language-service\"\n  }, \"Server in GraphQL\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"JavaScript\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Groovy\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/palantir\"\n  }, \"Palantir\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/palantir/groovy-language-server/\"\n  }, \"groovy-language-server\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Java\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"HTML\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"MS\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/Microsoft/vscode/tree/master/extensions/html-language-features/server\"\n  }, \"vscode-html-languageserver\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"TypeScript\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"JSON\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"MS\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://www.npmjs.com/package/vscode-json-languageserver\"\n  }, \"vscode-json-languageserver\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"TypeScript\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Java\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/georgewfraser\"\n  }, \"@georgewfraser\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/georgewfraser/vscode-javac\"\n  }, \"Java Compiler (javac) API-based Java support\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Java\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Javascript Flow\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://flow.org/\"\n  }, \"Facebook, Inc.\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/facebook/flow\"\n  }, \"flow\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"OCaml, JavaScript\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Javascript-Typescript\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://sourcegraph.com/\"\n  }, \"Sourcegraph\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/sourcegraph/javascript-typescript-langserver\"\n  }, \"javascript-typescript\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"TypeScript\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  })))), mdx(\"p\", null, \"\\u5176\\u4E2D monaco-editor \\u4E5F\\u6709\\u5BA2\\u6237\\u7AEF\\u7684\\u652F\\u6301 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.npmjs.com/package/monaco-languageclient\"\n  }, \"monaco-languageclient\"), \"\\uFF0C\\u4E5F\\u5C31\\u662F\\u53EF\\u4EE5\\u4F7F\\u7528 LSP \\u7684\\u3002\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Editor/IDE\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Maintainer\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Repository\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://code.visualstudio.com\"\n  }, \"Visual Studio Code\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Microsoft\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/Microsoft/vscode/\"\n  }, \"vscode\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://www.eclipse.org/che/\"\n  }, \"Eclipse Che\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Eclipse,Codenvy/TypeFox\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/eclipse/che/issues/1287\"\n  }, \"Che\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Eclipse IDE\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Eclipse,Red Hat\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://projects.eclipse.org/projects/technology.lsp4e/who\"\n  }, \"Eclipse community\"), \", \", mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://projects.eclipse.org/projects/technology.lsp4e\"\n  }, \"Eclipse LSP4E\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"emacs\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/vibhavp\"\n  }, \"Vibhav Pant\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/emacs-lsp/lsp-mode/\"\n  }, \"emacs language server client\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, \"*\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, mdx(\"a\", {\n    parentName: \"strong\",\n    \"href\": \"https://github.com/Microsoft/monaco-editor\"\n  }, \"MS Monaco Editor\"))), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, mdx(\"a\", {\n    parentName: \"strong\",\n    \"href\": \"https://github.com/TypeFox\"\n  }, \"TypeFox\"))), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, mdx(\"a\", {\n    parentName: \"strong\",\n    \"href\": \"https://www.npmjs.com/package/monaco-languageclient\"\n  }, \"monaco-languageclient\")))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Visual Studio\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Microsoft\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://marketplace.visualstudio.com/items?itemName=vsext.LanguageServerClientPreview\"\n  }, \"LSP Preview\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://atom.io/\"\n  }, \"Atom\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/\"\n  }, \"GitHub\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://www.npmjs.com/package/atom-languageclient\"\n  }, \"atom-languageclient\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/theia-ide/theia\"\n  }, \"Theia\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/theia-ide\"\n  }, \"theia-ide\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/theia-ide/theia\"\n  }, \"theia\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://www.sublimetext.com/\"\n  }, \"Sublime Text\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/rwols\"\n  }, \"Raoul Wols\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/sublimelsp/LSP\"\n  }, \"lsp\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\")))), mdx(\"p\", null, \"\\u670D\\u52A1\\u7AEF\\u6211\\u4EEC\\u4F7F\\u7528\\u7684 node.js\\uFF0C\\u4E5F\\u6709 SDK \\u7684\\u652F\\u6301\\uFF1A\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/Microsoft/vscode-languageserver-node\"\n  }, \"vscode-languageserver-node\")), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Language\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Maintainer\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Repository\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, \"*\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, \"node.js\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, \"MS\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, mdx(\"a\", {\n    parentName: \"strong\",\n    \"href\": \"https://github.com/Microsoft/vscode-languageserver-node\"\n  }, \"vscode-languageserver-node\")))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"C#\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"MS\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"work in progress by \", mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/daviwil\"\n  }, \"David Wilson\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Java\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Eclipse, TypeFox\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/eclipse/lsp4j\"\n  }, \"Eclipse LSP4J\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"PHP\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/felixfbecker\"\n  }, \"Felix Becker\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/felixfbecker/php-language-server\"\n  }, \"php-language-server\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"...\")))), mdx(\"p\", null, \"\\u6240\\u4EE5\\u7ED3\\u8BBA\\uFF1A\", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"\\u6709\\u5F88\\u591A\\u73B0\\u6210\\u7684\\u8BED\\u8A00\\u670D\\u52A1\\u3001\\u6709\\u73B0\\u6210\\u7684 LSP \\u5BA2\\u6237\\u7AEF\\u652F\\u6301\\u3001\\u6709\\u73B0\\u6210\\u7684\\u670D\\u52A1\\u7AEF\\u534F\\u8BAE\\u3002\\u6240\\u4EE5\\u80FD\\u591F\\u5B9E\\u73B0 LSP \\u7684 monaco-editor \\u652F\\u6301\\u6CA1\\u4EC0\\u4E48\\u95EE\\u9898\\u3002\")), mdx(\"h2\", null, \"\\u4E94\\u3001\\u670D\\u52A1\\u7AEF\\u96C6\\u6210 LSP\"), mdx(\"p\", null, \"\\u91CC\\u9762\\u7684\\u4E00\\u4E9B\\u5C01\\u88C5\\u548C dispose \\u4E4B\\u7C7B\\u7684\\u56E0\\u4E3A\\u7BC7\\u5E45\\u6CA1\\u6709\\u5199\\uFF0C\\u5B9E\\u9645\\u4E0A\\u90FD\\u9700\\u8981\\u8003\\u8651\\uFF0C\\u800C\\u4E14\\u6211\\u5728\\u5B9E\\u9645\\u9879\\u76EE\\u4E2D\\u8FD8\\u8003\\u8651\\u4E86\\uFF1A\\u591A\\u8BED\\u8A00\\u914D\\u7F6E\\u3001\\u540C\\u65F6\\u8FD0\\u884C\\u591A\\u8BED\\u8A00\\u3001\\u540C\\u4E00\\u4E2A socket.io \\u901A\\u9053\\u4F20\\u8F93\\u3001\\u91CD\\u8FDE\\u3001dispose\\u3001\\u9519\\u8BEF\\u663E\\u793A\\u3001\\u4E00\\u4E9B\\u8FB9\\u754C\\u60C5\\u51B5\\u7684\\u5904\\u7406\\u8F6C\\u6362\\u7B49\\u7B49\\uFF0C\\u5C01\\u88C5\\u903B\\u8F91\\u76F8\\u5BF9\\u591A\\u4E00\\u4E9B\\uFF0C\\u4E0B\\u9762\\u8BF4\\u7684\\u90FD\\u662F\\u4E00\\u4E9B\\u7B80\\u5316\\u7684\\u903B\\u8F91\\uFF0C\\u4E5F\\u5E76\\u6CA1\\u6709\\u4E25\\u683C\\u6D4B\\u8BD5\\u3002\"), mdx(\"h3\", null, \"1. \\u67B6\\u6784\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"\\u534F\\u8BAE\\uFF1Avscode-ws-jsonrpc\\uFF08\\u4E00\\u5957 json \\u683C\\u5F0F\\u6807\\u51C6\\u7684 rpc \\u901A\\u4FE1\\u534F\\u8BAE\\uFF09\\u3001WS \\u670D\\u52A1\\u7528\\u6765\\u4F20\\u8F93\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"\\u8BED\\u8A00\\u670D\\u52A1\\uFF1Atypescript-language-server\\uFF08ts \\u4E3A\\u4F8B\\uFF0C\\u4F7F\\u7528 typescript-language-server \\u4F5C\\u4E3A SDK \\u5F00\\u53D1\\uFF09\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"\\u670D\\u52A1\\u7AEF\\uFF1A\\u9879\\u76EE\\u5DE5\\u4F5C\\u76EE\\u5F55\\u3001vscode-ws-jsonrpc\\u3001\\u8FDB\\u7A0B\\u8FD0\\u884C\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"\\u5BA2\\u6237\\u7AEF\\uFF1Amonaco-editor\\u3001monaco-languageclient\\u3001vscode-ws-jsonrpc\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"\\u6570\\u636E\\u6D41\\u5411\\uFF1Aeditor -> languageclient -> jsonrpc -> ws -> jsonrpc -> ts language-server -> languageserver SDK\")), mdx(\"h3\", null, \"2. \\u670D\\u52A1\\u7AEF\\u548C\\u5BA2\\u6237\\u7AEF\\u7684\\u6570\\u636E\\u901A\\u9053 ws\"), mdx(\"p\", null, \"\\u4F7F\\u7528 socket.io \\u4F5C\\u4E3A jsonrpc \\u683C\\u5F0F\\u6570\\u636E\\u7684\\u4F20\\u8F93\\u901A\\u9053\\uFF0C\\u4E5F\\u5C31\\u662F language client \\u548C language server \\u7684\\u53CC\\u5411\\u6570\\u636E\\u4EA4\\u6D41\\u8F7D\\u4F53\\u3002\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"const os = require('os');\\nconst app = require('express')();\\nconst http = require('http').createServer(app);\\nconst io = require('socket.io')(http);\\n\\n// \\u901A\\u8FC7 socket.io \\u6765\\u8F93\\u5165\\u8F93\\u51FA\\nio.on('connection', (socket) => {\\n  socket.on('init_lang_server', (msg) => {\\n    // ... start the language server\\n  });\\n  // ...\\n});\\n\\n// \\u5F00\\u542F server\\napp.get('/', (req, res) => {\\n  res.sendFile(__dirname + '/index.html');\\n});\\nhttp.listen(3000, () => {\\n  console.log('listening on *:3000');\\n});\\n\")), mdx(\"h3\", null, \"3. rpc \\u534F\\u8BAE \\u548C ws socket\"), mdx(\"p\", null, \"\\u4E0B\\u9762\\u7684\\u4EE3\\u7801\\u662F\\u5C06 websocket \\u4F7F\\u7528\\u5230 jsonrpc \\u534F\\u8BAE\\u4E2D\\u7684\\u903B\\u8F91\\uFF0Cjsonrpc \\u81EA\\u5E26\\u7684\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"import { Socket } from \\\"socket.io\\\";\\nimport * as rpc from \\\"vscode-ws-jsonrpc\\\"\\nimport * as server from \\\"vscode-ws-jsonrpc/lib/server\\\"\\n\\nconst { WebSocketMessageReader, WebSocketMessageWriter } = rpc;\\nconst { createConnection } = server;\\n\\nconst socket: rpc.IWebSocket = adapterWS(rawWSSocket)\\n\\n// websocket io \\u8F6C\\u6362\\nconst reader = new WebSocketMessageReader(socket);\\nconst writer = new WebSocketMessageWriter(socket);\\n\\n// \\u5C06\\u8BFB\\u53D6\\u5199\\u5165\\u5C01\\u88C5\\u6210\\u6570\\u636E\\u8FDE\\u63A5\\u4EE5\\u4F9B\\u540E\\u7EED\\u4F7F\\u7528\\nconst socketConnection = createConnection(reader, writer);\\n\\n// \\u5C06 socket.io \\u7684 ws \\u8F6C\\u4E3A rpc \\u652F\\u6301\\u7684 ws\\uFF08\\uFF01\\uFF01\\uFF01\\u6B64\\u5904\\u662F\\u7B80\\u5316\\u7684\\u903B\\u8F91\\uFF09\\nfunction adapterWS(rawWSSocket: Socket): rpc.IWebSocket {\\n  return {\\n    send: content => {\\n      rawWSSocket.emit('data', {language, content})\\n    },\\n    onMessage: cb => {\\n      rawWSSocket.on('message', (data: any) => cb(data.content))\\n    },\\n    onError: cb => {\\n      rawWSSocket.on('error', (data: any) => cb(data))\\n    },\\n    onClose: cb => {\\n      rawWSSocket.on('close', (code: number, reason: string) => cb(code, reason))\\n    },\\n    dispose: () => {\\n      console.error(`[lsp]<${wsName}>{${language}} fakeSocket disconnect`)\\n    }\\n  }\\n}\\n\")), mdx(\"h3\", null, \"4. \\u8BED\\u8A00\\u670D\\u52A1\\u8FDB\\u7A0B\"), mdx(\"p\", null, \"\\u521B\\u5EFA\\u4E00\\u4E2A\\u8BED\\u8A00\\u670D\\u52A1\\u8FDB\\u7A0B\\u4F5C\\u4E3A\\u670D\\u52A1\\uFF0C\\u62FF\\u5230\\u8F93\\u5165\\u8F93\\u51FA\\u90E8\\u5206\\uFF0C\\u4EE5 ts \\u4E3A\\u4F8B\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"const { createStreamConnection } = server;\\n\\n// \\u5B9A\\u4E49\\u8FD0\\u884C\\u53C2\\u6570\\nconst tsServerProcessOptions = {\\n  command: \\\"node\\\",\\n  args: [path.resolve(__dirname, \\\"./langs/typescript.js\\\"), \\\"--stdio\\\"], // , ' --tsserver-log-file=ts-logs.txt', '--log-level=3'\\n  options: {}\\n}\\n\\n// \\u4F7F\\u7528 child_process \\u8FD0\\u884C\\u4E00\\u4E2A\\u5355\\u72EC\\u7684\\u8BED\\u8A00\\u5904\\u7406\\u8FDB\\u7A0B\\nlet rawProcess: child_process.ChildProcess = child_process.spawn(\\n  tsServerProcessOptions.command,\\n  tsServerProcessOptions.args,\\n  tsServerProcessOptions.options\\n);\\n\\n// \\u6839\\u636E\\u8FDB\\u7A0B\\u7684\\u8F93\\u5165\\u8F93\\u51FA\\u521B\\u5EFA\\u8FDE\\u63A5\\nconst streamConnection = createStreamConnection(rawProcess.stdout, rawProcess.stdin)\\n\")), mdx(\"p\", null, \"\\u5176\\u4E2D \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./langs/typescript.js\"), \" \\u5C31\\u4E00\\u884C\\u7B80\\u5355\\u7684\\u4EE3\\u7801\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"require('typescript-language-server/lib/cli');\\n\")), mdx(\"h3\", null, \"5. \\u5C06 ws jsonrpc \\u548C \\u8BED\\u8A00\\u670D\\u52A1 \\u7C98\\u5728\\u4E00\\u8D77\"), mdx(\"p\", null, \"\\u81F3\\u6B64 \\u6709\\u4E86\\u57FA\\u4E8E ws \\u6570\\u636E rpc \\u901A\\u9053\\uFF0C\\u6709\\u4E86 \\u8FDB\\u7A0B\\u7684\\u8F93\\u5165\\u8F93\\u51FA\\u6570\\u636E\\uFF0C\\u73B0\\u5728\\u53EA\\u9700\\u8981\\u7C98\\u5728\\u4E00\\u8D77\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"import * as rpc from \\\"vscode-ws-jsonrpc\\\"\\nconst { forward } = server;\\n\\n// \\u5C06\\u670D\\u52A1\\u8FDB\\u7A0B\\u7684\\u8F93\\u5165\\u8F93\\u51FA\\u8F6C\\u53D1\\u7ED9 socket \\u7684\\u8F93\\u5165\\u8F93\\u51FA\\nforward(socketConnection, streamConnection, message => {\\n  if (rpc.isRequestMessage(message)) {\\n    // console.log('\\u8BF7\\u6C42\\u6D88\\u606F: ');\\n\\n    // \\u4FEE\\u6B63 server \\u8FD0\\u884C\\u53C2\\u6570(moncao-languageclient \\u548C lsp \\u53C2\\u6570\\u4E0D\\u5339\\u914D)\\n\\n    // lsp \\u521D\\u59CB\\u5316\\u8BF7\\u6C42\\n    if (message.method === lsp.InitializeRequest.type.method) {\\n      message.params.processId = process.pid;\\n      message.params.initializationOptions = {}\\n    }\\n    if (message.method === lsp.FoldingRangeRequest.type.method) {\\n      message.params.update = function (i: any, v: any) {\\n        console.log(i, v)\\n      }\\n    }\\n    // if (message.method === lsp.DidOpenTextDocumentNotification.type.method) {\\n    //   message.params.create\\n    // }\\n  }else if (rpc.isResponseMessage(message)) {\\n  }else if (rpc.isNotificationMessage(message)) {\\n  } else {\\n  }\\n  return message;\\n});\\n\\nconsole.log(`[lsp] \\u5DE5\\u4F5C\\u533A\\u8BED\\u8A00\\u670D\\u52A1\\u5F00\\u542F\\u6210\\u529F`)\\n\")), mdx(\"p\", null, \"\\u4E00\\u4E2A \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"vscode-ws-jsonrpc\"), \" \\u51E0\\u4E4E\\u5C31\\u5C06\\u670D\\u52A1\\u7AEF\\u7684\\u5168\\u90E8\\u903B\\u8F91\\u89E3\\u51B3\\u4E86\\uFF0C\\u975E\\u5E38\\u6E05\\u695A\\u3001\\u4E5F\\u5F88\\u7B80\\u5355\\u3002\"), mdx(\"h2\", null, \"\\u516D\\u3001\\u5BA2\\u6237\\u7AEF\\u96C6\\u6210 LSP\"), mdx(\"h3\", null, \"1. \\u7ED1\\u5B9A monaco\"), mdx(\"p\", null, \"\\u5BA2\\u6237\\u7AEF\\u7684\\u5B9E\\u73B0\\u4E5F\\u4E0D\\u662F\\u5F88\\u590D\\u6742\\uFF0C\\u5148\\u662F\\u57FA\\u672C\\u7684\\u5904\\u7406\\u64CD\\u4F5C\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"import {\\n  MonacoLanguageClient, CloseAction, ErrorAction,\\n  MonacoServices, createConnection, ProtocolToMonacoConverter,\\n} from 'monaco-languageclient';\\n\\n// \\u4E00\\u5957 json \\u683C\\u5F0F\\u6807\\u51C6\\u7684 rpc \\u901A\\u4FE1\\u534F\\u8BAE\\nimport { listen, MessageConnection, createWebSocketConnection, ConsoleLogger, Message } from 'vscode-ws-jsonrpc';\\n\\n\\n// \\u8BBE\\u7F6E\\u5DE5\\u4F5C\\u6839\\u76EE\\u5F55\\nconst rootUri = `file:///workspace/`;\\n\\n// \\u5728\\u7F16\\u8F91\\u5668\\u4E0A\\u6DFB\\u52A0\\u8BED\\u8A00\\u670D\\u52A1\\nMonacoServices.install(editor, { rootUri });\\n\")), mdx(\"h3\", null, \"2. \\u521B\\u5EFA ws \\u627F\\u8F7D\\u6570\\u636E\\u4F20\\u8F93\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"import io from 'socket.io-client';\\n\\n// lsp \\u7684 ws \\u5730\\u5740\\uFF0C\\u521B\\u5EFA jsonrpc \\u7684 ws \\u5B9E\\u4F8B\\u4E0E\\u670D\\u52A1\\u5668\\u901A\\u4FE1\\nconst lspUrl = 'ws://127.0.0.1:7001/lsp';\\n\\n// ws \\u914D\\u7F6E\\nconst connectOpts: SocketIOClient.ConnectOpts = {\\n  query: {\\n    name: window.currentProjectName,\\n  },\\n  transports: ['websocket'],\\n  reconnection: true,\\n};\\n\\n// \\u5168\\u5C40\\u7684 socket \\u5BA2\\u6237\\u7AEF\\uFF08\\u53EF\\u4EE5\\u62D3\\u5C55\\u91CD\\u8FDE\\u3001\\u591A\\u8BED\\u8A00\\u670D\\u52A1\\u901A\\u9053\\u590D\\u7528\\u7B49\\uFF09\\nconst globalSocketIOClient = io(lspUrl, connectOpts);\\n\")), mdx(\"h3\", null, \"3. \\u5728 ws \\u4E0A\\u642D\\u5EFA jsonrpc \\u6570\\u636E\\u901A\\u9053\"), mdx(\"p\", null, \"\\u6BCF\\u4E2A\\u8BED\\u8A00\\u5BA2\\u6237\\u7AEF\\u4E0E server \\u76F8\\u8FDE\\u9700\\u8981\\u4E00\\u4E2A jsonrpc \\u7684 ws \\u901A\\u9053\\u3002\\u8FD9\\u91CC\\u4F7F\\u7528 ws \\u642D\\u5EFA\\u51FA\\u4E00\\u4E2A messageConnection\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"let messageConnection: MessageConnection = createWebSocketConnection({\\n  send: content => {\\n    globalSocketIOClient.emit('message', { language, content });\\n  },\\n  onMessage: cb => {\\n    connectionsMap[language].onMessageCallback.push(cb);\\n  },\\n  onError: cb => {\\n    connectionsMap[language].onError.push(cb);\\n  },\\n  onClose: cb => {\\n    connectionsMap[language].onClose.push(cb);\\n  },\\n  dispose: () => {\\n    globalSocketIOClient.close()\\n  }\\n}, new ConsoleLogger());\\n\")), mdx(\"h3\", null, \"4. \\u8BED\\u8A00\\u5BA2\\u6237\\u7AEF\"), mdx(\"p\", null, \"\\u901A\\u8FC7 MonacoLanguageClient \\u521B\\u5EFA\\u8BED\\u8A00\\u5BA2\\u6237\\u7AEF\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"const languageClient = new MonacoLanguageClient({\\n  'typescript',\\n  clientOptions: {\\n    documentSelector: ['typescript', 'javascript'],\\n    outputChannel: {\\n      append(value: any) {\\n        console.log(value)\\n      },\\n      appendLine(line: any) {\\n        console.log(line)\\n      },\\n      show(any: any) {\\n        console.log(any)\\n      },\\n      dispose() {\\n        // no-op\\n      }\\n    },\\n    errorHandler: {\\n      error: (error: Error, message: Message, count: number) => {\\n        console.log(error, message, count)\\n        return ErrorAction.Continue\\n      },\\n      closed: () => {\\n        console.log('closed')\\n        return CloseAction.DoNotRestart\\n      }\\n    },\\n  },\\n  // create a language client connection from the JSON RPC connection on demand\\n  connectionProvider: {\\n    get: (errorHandler, closeHandler) => {\\n      const func = createConnection(connection, errorHandler, closeHandler);\\n      return Promise.resolve(func);\\n    }\\n  }\\n});\\n\")), mdx(\"h3\", null, \"5. \\u542F\\u52A8\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u542F\\u52A8\\u672C\\u5730\\u7684\\u8BED\\u8A00\\u5BA2\\u6237\\u7AEF\\nlanguageClient.onReady().then(() => {\\n  lspOutputer.log(`\\u672C\\u5730 ${languageid} \\u8BED\\u8A00\\u5BA2\\u6237\\u7AEF\\u51C6\\u5907\\u5B8C\\u6BD5.`)\\n});\\nlanguageClient.start();\\n\\n// \\u544A\\u8BC9\\u670D\\u52A1\\u7AEF\\u542F\\u52A8\\u5BF9\\u5E94\\u7684\\u8BED\\u8A00\\u670D\\u52A1\\nglobalSocketIOClient.emit('initLang', { ws: window.currentProjectName, language: languageid });\\n\")), mdx(\"h2\", null, \"\\u4E03\\u3001\\u7ED3\\u675F\"), mdx(\"p\", null, \"\\u6700\\u540E\\u80FD\\u5F97\\u5230\\u4E00\\u4E2A\\u8BA9\\u4EBA\\u5F88\\u6FC0\\u52A8\\u7684\\u6548\\u679C\\uFF0C\\u4E0D\\u7528\\u52A0\\u8F7D\\u6587\\u4EF6\\u5185\\u5BB9\\u7B49\\u7B28\\u65B9\\u6CD5\\uFF0C\\u5C31\\u80FD\\u611F\\u77E5\\u8BED\\u8A00\\u7684\\u5404\\u79CD\\u670D\\u52A1\\uFF1A\"), mdx(\"div\", {\n    style: {\n      display: 'flex',\n      justifyContent: 'center'\n    }\n  }, mdx(WithFigcaption, {\n    title: \"\\u5728\\u7EBF IDE \\u9879\\u76EE\\u4E2D\\u96C6\\u6210 LSP \\u6548\\u679C\",\n    mdxType: \"WithFigcaption\"\n  }, mdx(\"video\", {\n    autoPlay: true,\n    loop: true,\n    controls: true,\n    style: {\n      maxWidth: '100%'\n    }\n  }, mdx(\"source\", {\n    src: \"https://fdb.ubug.io/storybook-videos/lsp-demo.mp4\",\n    type: \"video/mp4\"\n  })))), mdx(\"p\", null, \"LSP \\u7684\\u6982\\u5FF5\\u4E0D\\u662F\\u90A3\\u4E48\\u590D\\u6742\\uFF0C\\u4F46\\u662F\\u4E00\\u6574\\u5957\\u4E0B\\u6765\\u4E5F\\u6D89\\u53CA\\u5230\\u5F88\\u591A\\u6DF1\\u5C42\\u7684\\u6982\\u5FF5\\uFF0C\\u5982\\u679C\\u4E0D\\u662F\\u6709\\u524D\\u4EBA\\u7684\\u63A2\\u7D22\\uFF0C\\u6BD4\\u5982 VSCode\\u3001languageClient \\u7B49\\u5B9E\\u73B0\\uFF0C\\u8FD9\\u5757\\u5C06\\u4F1A\\u662F\\u4E00\\u5757\\u5F88\\u96BE\\u5543\\u7684\\u9AA8\\u5934\\uFF0C\\u597D\\u5728\\u6709 VSCode \\u8FD9\\u79CD\\u524D\\u7AEF\\u4F18\\u79C0\\u7F16\\u8F91\\u5668\\u7684\\u63A2\\u7D22\\u548C\\u5B9E\\u73B0\\uFF0C\\u5728 moncao-editor \\u4E0A\\u4E5F\\u6CBE\\u4E86\\u5F88\\u591A\\u5149\\uFF0C\\u5B9E\\u73B0\\u4E86\\u5F88\\u60CA\\u5947\\u7684\\u6548\\u679C\\u3002\"), mdx(\"p\", null, \"\\u6574\\u7BC7\\u6587\\u7AE0\\u7684\\u903B\\u8F91\\u548C\\u4EE3\\u7801\\u90FD\\u662F\\u5728\\u6211\\u9879\\u76EE\\u4E2D\\u622A\\u53D6\\u7684\\uFF0C\\u5927\\u6982\\u7387\\u662F\\u6CA1\\u529E\\u6CD5\\u76F4\\u63A5\\u62FF\\u6765\\u8FD0\\u884C\\uFF0C\\u4E0D\\u8FC7\\u5176\\u4E2D\\u7684\\u6D41\\u7A0B\\u548C\\u5173\\u952E\\u4F4D\\u7F6E\\u90FD\\u63D0\\u53CA\\u4E86\\uFF0C\\u5982\\u679C\\u4E0D\\u5ACC\\u5F03\\u6709\\u4EA4\\u6D41\\u7684\\u9700\\u8981\\u53EF\\u4EE5\\u5728 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/about/\"\n  }, \"\\u5173\\u4E8E\\u6211\"), \" \\u4E2D\\u8054\\u7CFB\\u6211~~\"), mdx(\"h2\", null, \"\\u516B\\u3001\\u66F4\\u591A\"), mdx(\"p\", null, \"\\u5728\\u6587\\u7AE0\\u53D1\\u5E03\\u7684\\u8FD9\\u6BB5\\u65F6\\u95F4\\uFF0C\\u6709\\u5F88\\u591A\\u5C0F\\u4F19\\u4F34\\u7ED9\\u6211\\u53D1\\u90AE\\u4EF6\\u95EE LSP \\u7684\\u96C6\\u6210\\u95EE\\u9898\\uFF0C\\u591A\\u8C22\\u5927\\u5BB6\\u7684\\u4EA4\\u6D41\\u3002\"), mdx(\"p\", null, \"LSP \\u7684\\u96C6\\u6210\\u786E\\u5B9E\\u5B9E\\u73B0\\u4E86\\uFF0C\\u529F\\u80FD\\u867D\\u7136\\u6CA1\\u90A3\\u4E48\\u5F3A\\u5927\\uFF0C\\u4F46\\u662F\\u94FE\\u8DEF\\u7B97\\u662F\\u8DD1\\u901A\\u4E86\\uFF0C\\u540E\\u7EED\\u4F18\\u5316\\u4E86\\u5F88\\u591A\\uFF0C\\u4E0D\\u8FC7\\u4E5F\\u4EC5\\u9650\\u4E8E TS\\u3001JSON\\u3001PHP \\u7B49\\u51E0\\u4E2A\\u7B80\\u5355\\u7684 server\\uFF0C\\u66F4\\u590D\\u6742\\u7684\\u96C6\\u6210\\u548C\\u53EF\\u9760\\u6027\\u5E76\\u6CA1\\u6709\\u82B1\\u90A3\\u4E48\\u591A\\u65F6\\u95F4\\uFF0C\\u6240\\u4EE5\\u8FD9\\u65B9\\u9762\\u6211\\u80FD\\u63D0\\u4F9B\\u7684\\u4E5F\\u5F88\\u6709\\u9650\\u3002\"), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u9879\\u76EE\\u662F\\u6211\\u7A7A\\u95F2\\u65F6\\u95F4\\u505A\\u7684\\uFF0C\\u975E\\u5E38\\u6709\\u610F\\u601D\\uFF0C\\u5F53\\u65F6\\u8FD9\\u4E2A\\u529F\\u80FD\\u70B9\\u4E5F\\u7FFB\\u4E86\\u597D\\u591A\\u6E90\\u7801\\u624D\\u5B9E\\u73B0\\u7684\\uFF0C\\u4F46\\u662F\\u4E5F\\u5E76\\u4E0D\\u662F\\u6BCF\\u5929\\u505A\\u7F16\\u8F91\\u5668\\uFF0C\\u91CC\\u9762\\u7684\\u5F88\\u591A\\u7EC6\\u8282\\u4E5F\\u4E0D\\u8BB0\\u5F97\\u4E86\\uFF0C\\u672C\\u6587\\u628A\\u5173\\u952E\\u7684\\u4F9D\\u8D56\\u548C\\u601D\\u8DEF\\u5199\\u4E86\\u4E0B\\u6765\\uFF0C\\u5982\\u679C\\u80FD\\u7ED9\\u4F60\\u63D0\\u4F9B\\u4E00\\u70B9\\u70B9\\u5F00\\u9614\\u601D\\u8DEF\\u4E5F\\u5C31\\u975E\\u5E38\\u5F00\\u5FC3\\u4E86\\uFF0C\\u5982\\u679C\\u5E2E\\u4E0D\\u4E86\\u4F60\\uFF0C\\u6211\\u73B0\\u5728\\u4E5F\\u6CA1\\u592A\\u591A\\u65F6\\u95F4\\u7FFB\\u4EE5\\u524D\\u7684\\u4EE3\\u7801\\u6574\\u7406\\u601D\\u8DEF\\uFF0C\\u975E\\u5E38\\u62B1\\u6B49\\u54C8\\u3002\"), mdx(\"p\", null, \"\\u80FD\\u529B\\u6709\\u9650\\uFF0C\\u6240\\u4EE5\\u9879\\u76EE\\u672C\\u8EAB\\u5F3A\\u70C8\\u7684\\u4E2A\\u4EBA\\u8272\\u5F69\\uFF0C\\u81EA\\u5DF1\\u4E5F\\u662F\\u53EA\\u90E8\\u7F72\\u5728\\u4E2A\\u4EBA\\u9879\\u76EE\\u4E2D\\uFF0C\\u4E5F\\u6CA1\\u6253\\u7B97\\u82B1\\u66F4\\u591A\\u7684\\u7CBE\\u529B\\u5728\\u8FD9\\uFF0C\\u6CA1\\u6253\\u7B97\\u5F00\\u6E90\\uFF0C\\u66F4\\u4E0D\\u53EF\\u80FD\\u7ED9\\u4F60\\u53D1\\u4E00\\u4EFD\\u3002\"));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"isCreatedByStatefulCreatePages":false,"id":"71379004-469b-5875-a99d-2c98b9578567","prev":{"fileAbsolutePath":"E:/u-codes/storybok/content/blog/workpad/workpad-part-7.md","id":"18538153-d038-550a-8fdf-eb8e6ce6f305","parent":{"name":"workpad-part-7","sourceInstanceName":"blog"},"excerpt":"一、什么是 DirtyDiff dirty 的意思在 Git 中表示当前本地代码与提交版本相比有修改，还没有提交。很多编辑器就会在行号旁边用颜色标识当前行的修改状态，用以提示用户当前文件状态，平时使用的时候是一个很好用的功能。 二、功能点 diffComputer 用来计算当前文件和 已提交文件的差别（修改、新增和删除） 将计算出来的差别转为 decorations 装饰器，将装饰器放到具体的每行里面 用户点击 decorations 后打开 peek 视图（OverlayWidget…","fields":{"title":"🌋 WebIDE 的开发记录其七（DirtyDiff 支持）","slug":"/blog/workpad-part-7","description":"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第七篇文章，谈谈怎么在 monaco-editor 上添加编辑器必备的 Git Dirty Diff 功能。","date":"2020-02-05","redirects":null,"datetime":"2020-02-05 22:43:52","categories":["webide"],"series":"WebIDE 的开发记录","tags":["思考","整理","WorkPad","WebIDE","云开发","Dirty Diff"],"status":"online"},"frontmatter":{"published":null,"tags":["思考","整理","WorkPad","WebIDE","云开发","Dirty Diff"],"theme":null,"slug":"workpad-part-7","date":"2020-02-05 22:43:52"},"body":"const _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsx mdx */\n\nconst _frontmatter = {\n  \"slug\": \"workpad-part-7\",\n  \"title\": \"🌋 WebIDE 的开发记录其七（DirtyDiff 支持）\",\n  \"date\": \"2020-02-05 22:43:52\",\n  \"author\": \"Ubug\",\n  \"description\": \"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第七篇文章，谈谈怎么在 monaco-editor 上添加编辑器必备的 Git Dirty Diff 功能。\",\n  \"series\": \"WebIDE 的开发记录\",\n  \"categories\": [\"webide\"],\n  \"tags\": [\"思考\", \"整理\", \"WorkPad\", \"WebIDE\", \"云开发\", \"Dirty Diff\"],\n  \"banner\": \"./WorkPad-demo.png\"\n};\nconst makeShortcode = name => function MDXDefaultShortcode(props) {\n  console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n  return mdx(\"div\", props);\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n      components\n    } = _ref,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h2\", null, \"\\u4E00\\u3001\\u4EC0\\u4E48\\u662F DirtyDiff\"), mdx(\"p\", null, \"dirty \\u7684\\u610F\\u601D\\u5728 Git \\u4E2D\\u8868\\u793A\\u5F53\\u524D\\u672C\\u5730\\u4EE3\\u7801\\u4E0E\\u63D0\\u4EA4\\u7248\\u672C\\u76F8\\u6BD4\\u6709\\u4FEE\\u6539\\uFF0C\\u8FD8\\u6CA1\\u6709\\u63D0\\u4EA4\\u3002\\u5F88\\u591A\\u7F16\\u8F91\\u5668\\u5C31\\u4F1A\\u5728\\u884C\\u53F7\\u65C1\\u8FB9\\u7528\\u989C\\u8272\\u6807\\u8BC6\\u5F53\\u524D\\u884C\\u7684\\u4FEE\\u6539\\u72B6\\u6001\\uFF0C\\u7528\\u4EE5\\u63D0\\u793A\\u7528\\u6237\\u5F53\\u524D\\u6587\\u4EF6\\u72B6\\u6001\\uFF0C\\u5E73\\u65F6\\u4F7F\\u7528\\u7684\\u65F6\\u5019\\u662F\\u4E00\\u4E2A\\u5F88\\u597D\\u7528\\u7684\\u529F\\u80FD\\u3002\"), mdx(\"div\", {\n    \"style\": {},\n    \"'flex',\": \"\",\n    \"justifycontent:\": \"\",\n    \"'center'}}\": \"\"\n  }, \"\\n  \", mdx(\"withfigcaption\", {\n    parentName: \"div\",\n    \"title\": \"动图演示实现的效果\"\n  }, \"\\n    \", mdx(\"img\", {\n    parentName: \"withfigcaption\",\n    \"src\": \"/git_dirty_diff2-dd9082be3f275f4bbcfefd15d958b638.gif\"\n  }), \"\\n  \")), mdx(\"p\", null, mdx(\"figure\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-figure\",\n    \"style\": {}\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"681px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/5667e149497d08e9c4e649271c74c23f/67e24/dirty_diff_3.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"73.74517374517376%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAACdElEQVQ4y42T6W7TQBSF/QxscbyO7XhfE++Jk5JWooAERIWChMT7P8bhjKNCgEr0x6c7vtdzZu4yiu0K5L6N90LF1jVRWjp0w4RpGsR8EoZhwLIsjOMIxbQtFCuB+9jBbZmiEwY04+lil4KbzQaKJQRSh4JVjF2RIksT2LYNTdOg6/ofSN/ffin2ILjdbinIzZ7noYkCXHcN+iJDEAQISRRF8H0fYRgiSRKUVYU8O8elP2Zc7pXCUnCaJgq6KxRRiB+Zi7v9iNuhw7Tfz6dJhmFA1/fo2xa7rkVDK8Vd14VNHMeZ05ZZHY9HKDaVXTqTosS4P2A6XKFmLSRVVWLNW6W8lWeZqPVXv1PVNWz0BTRZCp01Z9p5nkNxgxBenCBgWkVZIcsLJAzEKUWYWhDFCOMYgv99cVVErLfpuDBI6dj46i0h5C35LeurvLu7x82HE958POHTt++4Pd3h7ekz+tc32ExXaA9HVOOEpOlxaBoUtGk7ICNxM2DPEvR7ZjXuYLPBii0c5i8ghAs/YJFXvJW0ng+H9ZVWxjTNwEuyJNqFfaZqbFCIPg1g2iaUKPbZTW70LWLCD20K22d7sQ4iB2EkiDOv52/Orh9YqOsM2zI5C6ZVgHWXYXe9nslbD0XLzncrVH3wi7L3H4GxIZzRjOU8j0rMYsauh13dYmo6VGGMOslQ+ExbM7EyLKz0R5j9jC+W8Jm2pqowOD7KmnXakH2W48AOT+yuXE9pioGDO7LL/0I/Oz+y8yPf/Sjn0LQoaPEtcwwsT+D5QsULnrLgXD2gMoX/wjmWSDFLCjqCBQ88DnLNV9Gf3yVPfDLyf+M82PLF/ATrT7KMb1X0oAAAAABJRU5ErkJggg==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"重点实现的元素\",\n    \"title\": \"重点实现的元素\",\n    \"src\": \"/static/5667e149497d08e9c4e649271c74c23f/67e24/dirty_diff_3.png\",\n    \"srcSet\": [\"/static/5667e149497d08e9c4e649271c74c23f/ae269/dirty_diff_3.png 259w\", \"/static/5667e149497d08e9c4e649271c74c23f/a4dff/dirty_diff_3.png 518w\", \"/static/5667e149497d08e9c4e649271c74c23f/67e24/dirty_diff_3.png 681w\"],\n    \"sizes\": \"(max-width: 681px) 100vw, 681px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"figcaption\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-figcaption\"\n  }, \"\\u91CD\\u70B9\\u5B9E\\u73B0\\u7684\\u5143\\u7D20\"), \"\\n  \")), mdx(\"h2\", null, \"\\u4E8C\\u3001\\u529F\\u80FD\\u70B9\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"diffComputer \\u7528\\u6765\\u8BA1\\u7B97\\u5F53\\u524D\\u6587\\u4EF6\\u548C \\u5DF2\\u63D0\\u4EA4\\u6587\\u4EF6\\u7684\\u5DEE\\u522B\\uFF08\\u4FEE\\u6539\\u3001\\u65B0\\u589E\\u548C\\u5220\\u9664\\uFF09\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u5C06\\u8BA1\\u7B97\\u51FA\\u6765\\u7684\\u5DEE\\u522B\\u8F6C\\u4E3A decorations \\u88C5\\u9970\\u5668\\uFF0C\\u5C06\\u88C5\\u9970\\u5668\\u653E\\u5230\\u5177\\u4F53\\u7684\\u6BCF\\u884C\\u91CC\\u9762\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u7528\\u6237\\u70B9\\u51FB decorations \\u540E\\u6253\\u5F00 peek \\u89C6\\u56FE\\uFF08OverlayWidget + ViewZone\\uFF09\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"peekView \\u4E2D\\u663E\\u793A diff \\u7F16\\u8F91\\u5668\")), mdx(\"h2\", null, \"\\u4E09\\u3001\\u96C6\\u6210\"), mdx(\"h3\", null, \"1. diffComputer \\u8BA1\\u7B97\"), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u5982\\u679C\\u8BA9\\u6211\\u4EEC\\u81EA\\u5DF1\\u505A\\u7684\\u8BDD\\u4E5F\\u662F\\u80FD\\u5B9E\\u73B0\\u7684\\uFF0C\\u4F46\\u662F monaco-editor \\u91CC\\u9762\\u5DF2\\u7ECF\\u96C6\\u6210\\u4E86\\u8FD9\\u4E2A\\u5DE5\\u5177\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u56E0\\u4E3A\\u6211\\u4EEC\\u5F15\\u5165\\u7684\\u662F amd \\u89C4\\u8303\\u7684 monaco-editor\\uFF0C\\u8FD9\\u91CC\\u80FD\\u76F4\\u63A5\\u7528 require \\u5F15\\u5165\\u5185\\u90E8\\u7684\\u7EC4\\u4EF6\\uFF08\\u5982\\u679C\\u662F webpack \\u9700\\u8981\\u5355\\u72EC import \\u6253\\u5305\\uFF09\\nconst diffComputer = require('monaco-editor/esm/vs/editor/common/diff/diffComputer.js');\\n\\n// \\u5177\\u4F53\\u7684\\u8BA1\\u7B97\\u903B\\u8F91\\nconst DiffComputer = diffComputer.DiffComputer;\\n\\n// \\u8BA1\\u7B97\\u51FD\\u6570\\nconst computeDirtyDiff = (originalLines, modifiedModel) => {\\n  // \\u8FB9\\u754C\\u6761\\u4EF6\\u5904\\u7406\\n  if (!modifiedModel || modifiedModel.getValue() === '') return [];\\n  // \\u83B7\\u53D6\\u7F16\\u8F91\\u5668\\u5F53\\u524D\\u7684\\u5B9E\\u9645\\u5185\\u5BB9\\n  let modifiedLines = modifiedModel.getLinesContent();\\n  // \\u5229\\u7528\\u5185\\u7F6E\\u7684\\u8BA1\\u7B97\\u80FD\\u529B\\u8FDB\\u884C\\u8F93\\u51FA\\n  let diffComputer = new DiffComputer(originalLines, modifiedLines, {\\n        shouldComputeCharChanges: false,      // \\u4E0D\\u9700\\u8981\\u5B57\\u7B26\\u7EA7\\u522B\\u7684\\u5DEE\\u5F02\\uFF08\\u884C\\u7EA7\\u522B\\u548C\\u5B57\\u7B26\\u7EA7\\u522B\\uFF09\\n    shouldPostProcessCharChanges: false,  // \\u540E\\u7F6E\\u5904\\u7406\\u5B57\\u7B26\\u5DEE\\u5F02\\n    shouldIgnoreTrimWhitespace: false,    // \\u662F\\u5426\\u5FFD\\u7565\\u9996\\u5C3E\\u7A7A\\u683C\\u5DEE\\u5F02\\n    shouldMakePrettyDiff: true            // \\u8C03\\u6574 diff \\u66F4\\u7B26\\u5408\\u76F4\\u89C9\\n  });\\n  return diffComputer.computeDiff();\\n};\\n\")), mdx(\"p\", null, \"\\u6700\\u540E\\u5F97\\u5230\\u7684\\u7ED3\\u679C\\u4E00\\u4E2A json \\u5BF9\\u8C61\\u63CF\\u8FF0\\u4FEE\\u6539\\u548C\\u65B0\\u589E\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-json\"\n  }, \"[\\n  {\\n    \\\"originalStartLineNumber\\\": 24,\\n    \\\"originalEndLineNumber\\\": 0,\\n    \\\"modifiedStartLineNumber\\\": 25,\\n    \\\"modifiedEndLineNumber\\\": 25\\n  },\\n  {\\n    \\\"originalStartLineNumber\\\": 31,\\n    \\\"originalEndLineNumber\\\": 31,\\n    \\\"modifiedStartLineNumber\\\": 32,\\n    \\\"modifiedEndLineNumber\\\": 32\\n  },\\n  {\\n    \\\"originalStartLineNumber\\\": 34,\\n    \\\"originalEndLineNumber\\\": 0,\\n    \\\"modifiedStartLineNumber\\\": 36,\\n    \\\"modifiedEndLineNumber\\\": 36\\n  },\\n  {\\n    \\\"originalStartLineNumber\\\": 38,\\n    \\\"originalEndLineNumber\\\": 38,\\n    \\\"modifiedStartLineNumber\\\": 39,\\n    \\\"modifiedEndLineNumber\\\": 0\\n  }\\n]\\n\")), mdx(\"h3\", null, \"2. \\u5C06 diff \\u6570\\u636E\\u89E3\\u6790\\u4E3A decorations\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u83B7\\u53D6\\u7F16\\u8F91\\u5668\\u4E00\\u4E9B\\u56FA\\u5B9A\\u7684\\u5143\\u7D20\\u4F4D\\u7F6E\\nconst OverviewRulerLane = monaco.editor.OverviewRulerLane;\\n\\n// \\u5B9A\\u4E49\\u4FEE\\u6539\\u7C7B\\u578B\\nconst ChangeType = { Modify: 0, Add: 1, Delete: 2 };\\n\\n// decorations \\u7684\\u914D\\u7F6E\\uFF0C\\u5B9A\\u4E49\\u6807\\u8BB0\\u5E94\\u8BE5\\u5728\\u7684\\u4F4D\\u7F6E\\nconst baseOptions = {\\n  isWholeLine: true,\\n  position: OverviewRulerLane.Left + 2,\\n  overviewRuler: {\\n    color: 'RGBA(0, 122, 204, 0.6)',\\n    position: OverviewRulerLane.Left,\\n  }\\n}\\n// \\u4E0D\\u540C\\u7684 decorations \\u6709\\u4E0D\\u540C\\u7684 class name\\uFF0C\\u4EE5\\u4FBF css \\u5B9A\\u4E49\\u6837\\u5F0F\\nconst modifiedOptions = Object.assign({\\n  linesDecorationsClassName: 'dirty-diff-glyph dirty-diff-modified',\\n}, baseOptions);\\nconst addedOptions = Object.assign({\\n  linesDecorationsClassName: 'dirty-diff-glyph dirty-diff-added',\\n}, baseOptions);\\nconst deletedOptions = Object.assign({\\n  linesDecorationsClassName: 'dirty-diff-glyph dirty-diff-deleted',\\n}, baseOptions);\\n\\n// \\u6839\\u636E\\u4E0D\\u540C\\u7684\\u6570\\u636E\\uFF0C\\u80FD\\u89E3\\u6790\\u4E3A\\u4E0D\\u540C\\u7684\\u4FEE\\u6539\\u7C7B\\u578B\\nfunction getChangeType(change) {\\n  if (change.originalEndLineNumber === 0) {           // \\u65B0\\u589E\\u884C\\n    return ChangeType.Add;\\n  } else if (change.modifiedEndLineNumber === 0) {    // \\u5220\\u9664\\u884C\\n    return ChangeType.Delete;\\n  } else {                                            // \\u5176\\u4ED6\\u7684\\u90FD\\u662F\\u4FEE\\u6539\\n    return ChangeType.Modify;\\n  }\\n}\\n// \\u6839\\u636E\\u4E0A\\u9762\\u7684 diffChanges \\u8FDB\\u884C\\u8F6C\\u6362\\nconst generateDecorations = (changes) => {\\n  const decorations = changes.map((change) => {\\n    const changeType = getChangeType(change);\\n    const startLineNumber = change.modifiedStartLineNumber;\\n    const endLineNumber = change.modifiedEndLineNumber || startLineNumber;\\n\\n    // \\u6839\\u636E\\u4E0D\\u540C\\u7684\\u4FEE\\u6539\\u7C7B\\u578B\\uFF0C\\u5B9A\\u4E49\\u5F71\\u54CD\\u7684\\u884C\\u8303\\u56F4\\n    switch (changeType) {\\n      case ChangeType.Add:\\n        return {\\n          range: {\\n            startLineNumber: startLineNumber, startColumn: 1,\\n            endLineNumber: endLineNumber, endColumn: 1\\n          },\\n          options: addedOptions\\n        };\\n      case ChangeType.Delete:\\n        return {\\n          range: {\\n            startLineNumber: startLineNumber, startColumn: 1,\\n            endLineNumber: startLineNumber, endColumn: 1\\n          },\\n          options: deletedOptions\\n        };\\n      case ChangeType.Modify:\\n        return {\\n          range: {\\n            startLineNumber: startLineNumber, startColumn: 1,\\n            endLineNumber: endLineNumber, endColumn: 1\\n          },\\n          options: modifiedOptions\\n        };\\n    }\\n  });\\n  return decorations;\\n}\\n\")), mdx(\"p\", null, \"\\u600E\\u4E48\\u4F7F\\u7528\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u8BA1\\u7B97 diff changes\\nconst changesSave = computeDirtyDiff(originalLines, model);\\n// \\u6839\\u636E changes \\u5B9A\\u4E49\\u88C5\\u9970\\u5668\\nlet decorations = generateDecorations(changesSave);\\n// \\u5C06\\u88C5\\u9970\\u5668\\u66F4\\u65B0\\u5230\\u7F16\\u8F91\\u5668\\u4E2D\\ndecorationsSave = model.deltaDecorations(decorationsSave || [], decorations);\\n\")), mdx(\"p\", null, \"\\u522B\\u5FD8\\u4E86 css\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-css\"\n  }, \".monaco-editor .dirty-diff-glyph {\\n    margin-left: 5px;\\n    cursor: pointer;\\n    z-index: 5;\\n}\\n.monaco-editor .dirty-diff-glyph:before {\\n    position: absolute;\\n    content: \\\"\\\";\\n    height: 100%;\\n    width: 0;\\n    left: -2px;\\n    transition: width 80ms linear,left 80ms linear;\\n}\\n.monaco-editor .margin-view-overlays>div:hover>.dirty-diff-glyph:before {\\n    position: absolute;\\n    content: \\\"\\\";\\n    height: 100%;\\n    width: 9px;\\n    left: -6px;\\n}\\n.monaco-diff-editor .dirty-diff-glyph {\\n    display: none;\\n}\\n\\n/** delete **/\\n\\n.monaco-editor .dirty-diff-deleted:after {\\n    border-left: 4px solid #94151b;\\n    content: \\\"\\\";\\n    position: absolute;\\n    bottom: -4px;\\n    box-sizing: border-box;\\n    width: 4px;\\n    height: 0;\\n    z-index: 9;\\n    border-top: 4px solid transparent;\\n    border-bottom: 4px solid transparent;\\n    transition: border-top-width 80ms linear,border-bottom-width 80ms linear,bottom 80ms linear;\\n    pointer-events: none;\\n}\\n.monaco-editor .dirty-diff-deleted:before {\\n    background: #94151b;\\n    margin-left: 3px;\\n    height: 0;\\n    bottom: 0;\\n    transition: height 80ms linear;\\n}\\n.monaco-editor .margin-view-overlays>div:hover>.dirty-diff-deleted:after {\\n    bottom: 0;\\n    border-top-width: 0;\\n    border-bottom-width: 0;\\n}\\n\\n/* add modify */\\n.monaco-editor .dirty-diff-modified {\\n    border-left: 3px solid #0c7d9d;\\n}\\n.monaco-editor .dirty-diff-added {\\n    border-left: 3px solid #587c0c;\\n}\\n.monaco-editor .dirty-diff-modified:before {\\n    background: #0c7d9d;\\n}\\n.monaco-editor .dirty-diff-added:before {\\n    background: #587c0c;\\n}\\n\\n/* peekview */\\n\\n.ubug-overlay {\\n    border-top: 1px solid #00BCD4;\\n    border-bottom: 1px solid #00BCD4;\\n    display: flex;\\n    flex-direction: column;\\n}\\n.ubug-overlay-name {\\n    font-weight: bold;\\n}\\n.ubug-overlay-title {\\n    background: #3b4448;\\n    color: #fff;\\n    display: flex;\\n    line-height: 20px;\\n    height: 20px;\\n    padding: 0 10px;\\n    justify-content: space-between;\\n    border-bottom: 1px solid #00bcd4;\\n}\\n\\n.ubug-overlay-type-0{border-color: #0c7d9d;}\\n.ubug-overlay-type-0 .ubug-overlay-title{border-bottom-color: #0c7d9d;}\\n\\n.ubug-overlay-type-1{border-color: #587c0c;}\\n.ubug-overlay-type-1 .ubug-overlay-title{border-bottom-color: #587c0c;}\\n\\n.ubug-overlay-type-2{border-color: #94151b;}\\n.ubug-overlay-type-2 .ubug-overlay-title{border-bottom-color: #94151b;}\\n\\n.ubug-overlay-editor {\\n    flex: auto;\\n}\\n.ubug-overlay-btns {\\n    display: flex;\\n}\\n.ubug-overlay-btn {\\n    font-size: 20px;\\n    line-height: 18px;\\n    opacity: .6;\\n    width: 20px;\\n    text-align: center;\\n}\\n.ubug-overlay-btn:hover {\\n    opacity: 1;\\n}\\n\")), mdx(\"h3\", null, \"3. line dirty diff \\u6548\\u679C\"), mdx(\"p\", null, \"\\u6211\\u4EEC\\u80FD\\u5F97\\u5230\\u8FD9\\u6837\\u7684\\u6548\\u679C\\uFF1A\"), mdx(\"p\", null, mdx(\"figure\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-figure\",\n    \"style\": {}\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"561px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/5995ad77444aaff53f6ed86d0046f831/04dec/dirty_diff_4.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"27.7992277992278%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsSAAALEgHS3X78AAAA8UlEQVQY05WPy2rDMBBF/Q1dFL8VyXVkyZVsxw9sy110EQLJqlDoshQK/f8vuLXUB7SEQBaHo5kLMyOPcYbn9Aan9BYm9TGvJEmCOE5Wx+59Dd4mZzgUFCctcOh3EJQgDMPvofEfn+N/5hHK8M4jvFZbHBXHvmBgjF4ccvlCQqD4FlXTgAiJu3uFLMvg+7679BxBEDh+6iiKfvFYnqOlKYwu8fQw41hJaKVQliXqukazLtJaQ609a1sPw+CwPSklhBDONvc2qsZbHuJjV+DlccHeTFiWBeM4ou97N7TrOrRti9kYTNNXbm3hnLsfUUqdPwHx+qzxgSPjHAAAAABJRU5ErkJggg==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"能够实现的效果\",\n    \"title\": \"能够实现的效果\",\n    \"src\": \"/static/5995ad77444aaff53f6ed86d0046f831/04dec/dirty_diff_4.png\",\n    \"srcSet\": [\"/static/5995ad77444aaff53f6ed86d0046f831/ae269/dirty_diff_4.png 259w\", \"/static/5995ad77444aaff53f6ed86d0046f831/a4dff/dirty_diff_4.png 518w\", \"/static/5995ad77444aaff53f6ed86d0046f831/04dec/dirty_diff_4.png 561w\"],\n    \"sizes\": \"(max-width: 561px) 100vw, 561px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"figcaption\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-figcaption\"\n  }, \"\\u80FD\\u591F\\u5B9E\\u73B0\\u7684\\u6548\\u679C\"), \"\\n  \")), mdx(\"h3\", null, \"4. peekView\"), mdx(\"p\", null, \"\\u5B8C\\u6210\\u4E0A\\u9762\\u7684\\u6548\\u679C\\u5176\\u5B9E\\u5DF2\\u7ECF\\u80FD\\u591F\\u6709\\u751F\\u4EA7\\u529B\\u7684\\uFF0C\\u4E0D\\u8FC7\\u4E00\\u822C\\u7684 dirtyDiff \\u529F\\u80FD\\u90FD\\u9700\\u8981\\u642D\\u914D\\u70B9\\u51FB\\u67E5\\u770B\\u7684\\u529F\\u80FD\\uFF0C\\u4E5F\\u5C31\\u662F\\u70B9\\u51FB\\u884C\\u9996\\u7684\\u6807\\u8BB0\\uFF0C\\u80FD\\u591F\\u67E5\\u770B\\u5230\\u5177\\u4F53\\u54EA\\u4E9B dirty\\u3002\"), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u529F\\u80FD\\u7684\\u5B9E\\u73B0\\u4E5F\\u8C03\\u7814\\u4E86\\u5F88\\u4E45\\uFF0C\\u600E\\u4E48\\u624D\\u80FD\\u5728\\u7F16\\u8F91\\u5668\\u4E2D\\u5D4C\\u5165\\u4E00\\u4E2A diff \\u7F16\\u8F91\\u5668\\u5462\\uFF1F\\u4E00\\u756A\\u641C\\u7D22\\u4E4B\\u540E\\u53D1\\u73B0\\u4E86 OverlayWidget \\u548C ViewZone \\u8FD9\\u4E24\\u4E2A\\u4E1C\\u897F\\u3002\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"ViewZone \\u662F\\u8D1F\\u8D23\\u5728\\u7F16\\u8F91\\u5668\\u5185\\u90E8\\u884C\\u4E4B\\u95F4\\u5F00\\u542F\\u4E00\\u7247\\u533A\\u57DF\\u7684\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"editor.changeViewZones((changeAccessor) => {\\n  let viewZoneId = changeAccessor.addZone({\\n    afterLineNumber: endLineNum,\\n    suppressMouseDown: true,\\n    heightInLines: lineHeight + 1, // one more for the title\\n    domNode: zoneNode,\\n    onDomNodeTop: top => {\\n      overlayDom.style.top = top + \\\"px\\\";\\n    },\\n    onComputedHeight: height => {\\n      overlayDom.style.height = height + \\\"px\\\";\\n    }\\n  });\\n  // editor.setPosition({ column: 1, lineNumber: endLineNum });\\n  editor.revealLineInCenter(endLineNum);\\n  // this.renderDiffEditorAtDom(editor, endLineNum, overlayDom);\\n  // this.overlays.push({ zone: viewZoneId, editor: editor, overlayWidget, index });\\n});\\n\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"OverlayWidget \\u662F\\u8D1F\\u8D23\\u5728\\u7F16\\u8F91\\u5668\\u4E0A\\u6DFB\\u52A0\\u4E00\\u4E2A dom \\u8282\\u70B9\\u7684\\uFF0C\\u7136\\u540E\\u624B\\u52A8\\u8FFD\\u8E2A zone \\u7684\\u4F4D\\u7F6E\\u548C\\u9AD8\\u5EA6\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"editor.addOverlayWidget({\\n  getId: () => `${path} - ${index}`,\\n  getDomNode: () => document.createElement('div'),\\n  getPosition: () => null\\n});\\n\")))), mdx(\"p\", null, \"\\u4F7F\\u7528\\u8FD9\\u4E24\\u4E2A\\u63A5\\u53E3\\u7684\\u539F\\u56E0\\u662F\\u53EF\\u4EE5\\u5185\\u5D4C\\u5728\\u7F16\\u8F91\\u5668\\u7684\\u6548\\u679C\\uFF0C\\u4E0D\\u4F1A\\u968F\\u7740\\u6EDA\\u52A8\\u70B9\\u51FB\\u7B49\\u53D8\\u66F4\\u3002\"), mdx(\"p\", null, \"\\u5B8C\\u6574\\u7684\\u6548\\u679C\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u7F16\\u8F91\\u5668\\u70B9\\u51FB\\u76D1\\u542C\\uFF0C\\u8FC7\\u6EE4\\u7279\\u5B9A\\u7ED1\\u5B9A\\u7684 editor\\uFF0C\\u76EE\\u6807\\u662F\\u521A\\u624D\\u6DFB\\u52A0\\u7684\\u88C5\\u9970\\u5668\\neditor.onMouseDown((e) => {\\n  if (e.target.type === monaco.editor.MouseTargetType.GUTTER_LINE_DECORATIONS &&\\n    /dirty-diff/.test(e.target.element.className)) {\\n    const path = getPathFromModel(editor.getModel());\\n    const lineNumber = e.target.position.lineNumber;\\n    if (this.updaters[path]) {\\n      // \\u83B7\\u53D6\\u4FEE\\u6539\\u7684\\u4F4D\\u7F6E\\n      const changeIndex = this.updaters[path].getChangeIndex(lineNumber);\\n      // \\u5F00\\u8F9F\\u4E00\\u4E2A\\u533A\\u57DF\\u653E\\u7F6E diff editor\\n      this.renderOverlay(editor, changeIndex);\\n    }\\n  }\\n});\\n\\n// \\u5C06\\u5FEB\\u901F\\u9884\\u89C8\\u7684\\u57FA\\u7840 dom \\u6CE8\\u5165\\u5230 editor \\u4E2D\\nrenderOverlay = (editor: monaco.editor.IStandaloneCodeEditor, ind: number) => {\\n  this.cleanOverlay();\\n\\n  const path = getPathFromModel(editor.getModel());\\n\\n  const { endLineNum, linesNum, changesNum, index, changeType } = this.updaters[path].getChangeInfo(ind);\\n  let lineHeight = linesNum * 2 + 3 * 2; // \\u4FDD\\u8BC1\\u67E5\\u770B diff \\u540E\\u4E0A\\u4E0B\\u8FD8\\u6709\\u4E09\\u884C\\n  lineHeight = lineHeight > 14 ? 14 : (lineHeight < 8 ? 8 : lineHeight);\\n\\n  this.peekViewIndex = { path, ind, changesNum };\\n\\n  // peek View \\u4E0A\\u7684\\u4E00\\u4E9B\\u70B9\\u51FB\\u529F\\u80FD\\n  const onAddCommit: any = null; // () => { console.log('\\u63D0\\u4EA4\\u529F\\u80FD\\u5F85\\u5B9A'); }  // command.executeCommand('Git.Commit', '');\\n  const onCloseCommit = () => { this.cleanOverlay(); }\\n  const onPrevIndex = () => { this.showPrevChange(); }\\n  const onNextIndex = () => { this.showNextChange(); }\\n\\n  // \\u51C6\\u5907\\u4E00\\u4E2A dom \\u8282\\u70B9\\n  let overlayDom = prepareOverlayWidget(index, changesNum, changeType, path, onAddCommit, onPrevIndex, onNextIndex, onCloseCommit);\\n  // \\u4FEE\\u6B63\\u5E76\\u8DDF\\u8E2A\\u5BBD\\u5EA6\\uFF0C\\u4E0D\\u4F1A\\u8D85\\u8FC7 minimap \\u7684\\u4F4D\\u7F6E\\n  fixOverlayWidth(editor.getLayoutInfo(), overlayDom);\\n\\n  // \\u6DFB\\u52A0 overlay widget\\n  let overlayWidget: monaco.editor.IOverlayWidget = {\\n    getId: () => `${path} - ${index}`,\\n    getDomNode: () => overlayDom,\\n    getPosition: () => null\\n  };\\n  editor.addOverlayWidget(overlayWidget);\\n\\n  // \\u6DFB\\u52A0 view zone\\uFF0C\\u8DDF\\u8E2A\\u9AD8\\u5EA6\\u548C\\u4F4D\\u7F6E\\n  let zoneNode = createDivWithClass(null, null, null, { background: '#8effc9' });\\n  editor.changeViewZones((changeAccessor) => {\\n    let viewZoneId = changeAccessor.addZone({\\n      afterLineNumber: endLineNum,\\n      suppressMouseDown: true,\\n      heightInLines: lineHeight + 1, // one more for the title\\n      domNode: zoneNode,\\n      onDomNodeTop: top => {\\n        overlayDom.style.top = top + \\\"px\\\";\\n      },\\n      onComputedHeight: height => {\\n        overlayDom.style.height = height + \\\"px\\\";\\n      }\\n    });\\n    // editor.setPosition({ column: 1, lineNumber: endLineNum });\\n    // \\u8BA9\\u76EE\\u6807\\u884C\\u81EA\\u52A8\\u5230\\u7F16\\u8F91\\u5668\\u4E2D\\u592E\\n    editor.revealLineInCenter(endLineNum);\\n    // \\u5728 overlay \\u7684\\u8282\\u70B9\\u4E0A\\u6DFB\\u52A0 diff editor\\n    this.renderDiffEditorAtDom(editor, endLineNum, overlayDom);\\n    this.overlays.push({ zone: viewZoneId, editor: editor, overlayWidget, index });\\n  });\\n}\\n\")), mdx(\"p\", null, \"\\u81F3\\u6B64\\uFF0C\\u5B8C\\u6210\\u4E86\\u70B9\\u51FB\\u88C5\\u9970\\u5668\\u67E5\\u770B\\u5177\\u4F53\\u5DEE\\u5F02\\u5BF9\\u6BD4\\u7684\\u6548\\u679C\"), mdx(\"h2\", null, \"\\u56DB\\u3001\\u7ED3\\u8BBA\"), mdx(\"p\", null, \"\\u8FD9\\u4E2A\\u63D2\\u4EF6\\u7814\\u7A76\\u4E86\\u6BD4\\u8F83\\u591A\\uFF0C\\u4F46\\u662F\\u6700\\u540E\\u53C2\\u52A0\\u4E86\\u817E\\u8BAF\\u65D7\\u4E0B \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Coding\"), \" \\u4E3B\\u529E\\u7684 \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"CloudIDE\"), \" \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://studio.qcloud.coding.net/campaign/favorite-plugins/detail\"\n  }, \"\\u63D2\\u4EF6\\u6BD4\\u8D5B\"), \"\\uFF0C\\u8FD9\\u4E2A\\u63D2\\u4EF6\\u5B89\\u88C5\\u91CF\\u975E\\u5E38\\u5927\\uFF0C\\u62FF\\u5230\\u4E86\\u4F18\\u80DC\\u5956\\uFF0C\\u6700\\u540E\\u88AB\\u5B98\\u65B9\\u5185\\u7F6E\\uFF0C\\u8FD8\\u662F\\u5F88\\u503C\\u5F97\\u561A\\u745F\\u7684~~\"), mdx(\"p\", null, mdx(\"figure\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-figure\",\n    \"style\": {}\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"762px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/d4634d854e6eb9eda534113992f6bb22/2722f/reward.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"68.33976833976834%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAADXElEQVQ4yz2RW1NbVRiG92+wN7YQIOSwd87ZJDsnIMEUaUbBItPOcFEVeyPW1pnKjVcde+MvcZzxJ+idM53RqaJlwEISQnMkgXDKAXIqPK5sKBfPrLXXfr9vvev9pNJ2h3LpgFQqx85OkdZpl7Nmh9NGW9C53jdqXQ5KQluusr1doHZ8Kv5dai/Xrq6T2s0epeK+TiZTEBSplA/ZqxzpHFRPqO6fUK+d0ay1KZWqZLO7pNI5crmyrunr9/eOOTpsiIatHvV6l0a9Q7Pe0gvfuWuKtVlvc96DXueC9lmPk6OGcNu61vTP3tFrXyD1OrC5+juFTErcuEc+X9FvPT5qcnLcpHZyKlzW9CZnzTY//fwLr9ZTbCWzIqISu8Lx7pXrYmGv7/CccmaN/Js0axsZXv69zqu1LTY3d3gtSKfzJFNZvaglXBxWDqkmMzQO63Tb57qzTuvttUupf9gRLtsHNZr5Ei0Rckdc0n/mefeSi7fo32enoqHIM72RIi0cZrIVkXmJLTHQZCovci0g9TNJioDTG0n+efGSUr6sD6hYqAhX/WGJGK7Crx/VON4/YF1o/3jxJ6u//cq/f63yev0/itkchTdZpPj0hywlbvNpfAp/MMzExCSTfSajxGIxfX//3n2++voRXy5/x4OnP/Lt9894+miFpYcrLC4/48Hj53z+5DlfPPkB6dbAAAGjgaBiZXBoCMPgIMMjIxjE/v2bN7lx4z3sgRjehWXk+CLTC5+x9Pgb4pPTOCOzWIJzWAIfY4t8gje2gGS2WPC7XUIwQSAQwOf3o7kc2GUrNrMJs2EA+0QCdXEF3/xDErNzTH10l/DtO0SCfqIRjbCmEo9FuDubQPKMaaihcbRIFJfqR3Z5ccgKssWKbFVQbTa8fg0tFCE4+QGxO3NEZ2YJTc0gKzZsDjd2hwuH043PpyFZZDN2l4ziNGO1j+qYFCMmeQSjQLaZUN1OXC4nqtdDKBggLAhoPqyyCdluRdXGUP1uAkEVyW41o3mcBFVR4LDiEiK3YtbxCpThQdHMTVQMaDwcZmY8TDgyTigUwumW8YzJjIVVfEGHaGoXGRqFq1ETFqMJo2FIMHy1DjEqGL41gKIoeDweMfEJ7s3Pk0gkiEajmPsZW2XxZAc2RcbldPA/0+7wFcsU8LYAAAAASUVORK5CYII=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"比赛优胜\",\n    \"title\": \"比赛优胜\",\n    \"src\": \"/static/d4634d854e6eb9eda534113992f6bb22/2722f/reward.png\",\n    \"srcSet\": [\"/static/d4634d854e6eb9eda534113992f6bb22/ae269/reward.png 259w\", \"/static/d4634d854e6eb9eda534113992f6bb22/a4dff/reward.png 518w\", \"/static/d4634d854e6eb9eda534113992f6bb22/2722f/reward.png 762w\"],\n    \"sizes\": \"(max-width: 762px) 100vw, 762px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"figcaption\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-figcaption\"\n  }, \"\\u6BD4\\u8D5B\\u4F18\\u80DC\"), \"\\n  \")), mdx(\"h2\", null, \"\\u4E94\\u3001\\u6700\\u540E\\u7684\\u6700\\u540E\"), mdx(\"p\", null, \"\\u5305\\u62EC\\u4E4B\\u524D\\u7684\\u51E0\\u4E2A\\u529F\\u80FD\\uFF1Atextmate\\u3001LSP \\u548C\\u8FD9\\u4E2A DirtyDiff \\u529F\\u80FD\\uFF0C\\u5199\\u6210\\u6587\\u5B57\\u4E4B\\u540E\\u53D1\\u73B0\\u5F88\\u591A\\u5E76\\u4E0D\\u590D\\u6742\\uFF0C\\u6D41\\u7A0B\\u4E5F\\u5F88\\u6E05\\u6670\\uFF0C\\u4F46\\u662F\\u5F53\\u521D\\u786E\\u5B9E\\u82B1\\u4E86\\u5F88\\u591A\\u7684\\u65F6\\u95F4\\u53BB\\u627E\\u5B9E\\u73B0\\u3001\\u8C03\\u8BD5\\u8FD0\\u884C\\uFF0C\\u6700\\u7EC8\\u5F88\\u8270\\u96BE\\u7684\\u624D\\u8FBE\\u6210\\u60F3\\u8981\\u7684\\u6548\\u679C\\u3002\\u6240\\u4EE5\\u4E00\\u4E2A\\u4E0D\\u719F\\u6089\\u7684\\u9886\\u57DF\\u5982\\u679C\\u5B9E\\u73B0\\u67D0\\u4E9B\\u4E1A\\u52A1\\uFF0C\\u77E5\\u9053\\u60F3\\u8981\\u7684\\u6548\\u679C\\u4F46\\u662F\\u771F\\u7684\\u6CA1\\u6709\\u4E00\\u70B9\\u5934\\u7EEA\\uFF0C\\u786E\\u5B9E\\u9700\\u8981\\u82B1\\u8D39\\u5F88\\u591A\\u7684\\u7CBE\\u529B\\u6765\\u8865\\u5145\\u76F8\\u5173\\u7684\\u80FD\\u529B\\uFF0C\\u6700\\u540E\\u624D\\u80FD\\u4E0D\\u8D39\\u529B\\u7684\\u8BF4\\u51FA\\u5176\\u4E2D\\u7684\\u539F\\u7406\\u548C\\u5B9E\\u73B0\\u3002\"), mdx(\"p\", null, \"\\u8FD9\\u4E9B\\u4E1C\\u897F\\u5982\\u679C\\u4EA4\\u7ED9\\u4E0D\\u719F\\u6089\\u7684\\u4EBA\\u505A\\uFF0C\\u9700\\u8981\\u82B1\\u8D39\\u5F88\\u591A\\u7684\\u65F6\\u95F4\\u8C03\\u7814\\u5176\\u4E2D\\u7684\\u6BCF\\u4E2A\\u6982\\u5FF5\\uFF0C\\u6240\\u4EE5\\u7ECF\\u9A8C\\u786E\\u5B9E\\u662F\\u4E0D\\u53EF\\u66FF\\u4EE3\\u7684\\u3002\\u4E0D\\u8FC7\\u5BF9\\u4E8E\\u6211\\u6765\\u8BF4\\uFF0C\\u627E\\u8D44\\u6599\\u3001\\u770B\\u6E90\\u7801\\u5230\\u6DF1\\u591C\\uFF0C\\u7136\\u540E\\u628A\\u6548\\u679C\\u6210\\u529F\\u5B9E\\u73B0\\u7684\\u6B23\\u559C\\u5F88\\u96BE\\u5FD8\\u8BB0~~\"), mdx(\"p\", null, \"WorkPad WebIDE \\u7684\\u4E00\\u7CFB\\u5217\\u6587\\u7AE0\\u5199\\u4E86\\u8FD9\\u4E9B\\uFF0C\\u6DB5\\u76D6\\u4E86\\u503C\\u5F97\\u8BF4\\u7684\\u90E8\\u5206\\uFF0C\\u7814\\u7A76\\u6BD4\\u8F83\\u591A\\u7684\\u5730\\u65B9\\uFF0C\\u9664\\u6B64\\u4E4B\\u5916\\u8FD8\\u6709\\u5F88\\u591A\\u7EC6\\u679D\\u672B\\u8282\\u3001\\u82B1\\u4E86\\u5F88\\u591A\\u7CBE\\u529B\\u7684\\u5730\\u65B9\\u3001\\u90FD\\u6CA1\\u6709\\u6D89\\u53CA\\uFF0C\\u4E0D\\u662F\\u4E0D\\u503C\\u5F97\\u8BF4\\uFF0C\\u6BD5\\u7ADF\\u4E0D\\u53EF\\u80FD\\u9762\\u9762\\u4FF1\\u5230\\u3002\\u76EE\\u524D\\u5148\\u5199\\u8FD9\\u4E9B\\uFF0C\\u66F4\\u591A\\u7684\\u5185\\u5BB9\\u7B49\\u6709\\u65F6\\u95F4\\u5F52\\u6863\\u4E0B\\u518D\\u5F62\\u6210\\u6587\\u5B57~\"));\n}\n;\nMDXContent.isMDXComponent = true;"},"next":{"fileAbsolutePath":"E:/u-codes/storybok/content/blog/workpad/workpad-part-5.md","id":"375813ee-f566-5c96-960c-56022600d585","parent":{"name":"workpad-part-5","sourceInstanceName":"blog"},"excerpt":"一、为什么要用 textmate 而不是内置的？ 实现 IDE 的过程中好奇为什么 moanco-editor 和 vscode 的高亮不太一样，比较简陋很不舒服，一番搜索发现  monaco-editor  的语言支持使用的是内置的  Monarch  这个语法高亮支持。 官方的解释  Why doesn't the editor support TextMate grammars? ： 主要就是因为  Textmate  语法解析依赖的  Oniguruma  是一个 C…","fields":{"title":"🌋 WebIDE 的开发记录其五（monaco-editor + textmate）","slug":"/blog/workpad-part-5","description":"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第五篇文章，谈谈怎么在 monaco-editor 用 textmate 替换内置语法和高亮的。","date":"2020-01-27","redirects":null,"datetime":"2020-01-27 20:03:43","categories":["webide"],"series":"WebIDE 的开发记录","tags":["思考","整理","WorkPad","WebIDE","云开发","在线编辑器"],"status":"online"},"frontmatter":{"published":null,"tags":["思考","整理","WorkPad","WebIDE","云开发","在线编辑器"],"theme":null,"slug":"workpad-part-5","date":"2020-01-27 20:03:43"},"body":"const _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsx mdx */\n\nconst _frontmatter = {\n  \"slug\": \"workpad-part-5\",\n  \"title\": \"🌋 WebIDE 的开发记录其五（monaco-editor + textmate）\",\n  \"date\": \"2020-01-27 20:03:43\",\n  \"author\": \"Ubug\",\n  \"description\": \"WorkPad 是一个非常有意思的项目，花了很多空闲时间打磨，光基础架构的重构就好几遍，现在略微记录下开发的思路和想法。本文为第五篇文章，谈谈怎么在 monaco-editor 用 textmate 替换内置语法和高亮的。\",\n  \"series\": \"WebIDE 的开发记录\",\n  \"categories\": [\"webide\"],\n  \"tags\": [\"思考\", \"整理\", \"WorkPad\", \"WebIDE\", \"云开发\", \"在线编辑器\"],\n  \"banner\": \"./WorkPad-demo.png\"\n};\nconst makeShortcode = name => function MDXDefaultShortcode(props) {\n  console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n  return mdx(\"div\", props);\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n      components\n    } = _ref,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h2\", null, \"\\u4E00\\u3001\\u4E3A\\u4EC0\\u4E48\\u8981\\u7528 textmate \\u800C\\u4E0D\\u662F\\u5185\\u7F6E\\u7684\\uFF1F\"), mdx(\"p\", null, \"\\u5B9E\\u73B0 IDE \\u7684\\u8FC7\\u7A0B\\u4E2D\\u597D\\u5947\\u4E3A\\u4EC0\\u4E48 moanco-editor \\u548C vscode \\u7684\\u9AD8\\u4EAE\\u4E0D\\u592A\\u4E00\\u6837\\uFF0C\\u6BD4\\u8F83\\u7B80\\u964B\\u5F88\\u4E0D\\u8212\\u670D\\uFF0C\\u4E00\\u756A\\u641C\\u7D22\\u53D1\\u73B0 \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"monaco-editor\"), \" \\u7684\\u8BED\\u8A00\\u652F\\u6301\\u4F7F\\u7528\\u7684\\u662F\\u5185\\u7F6E\\u7684 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://microsoft.github.io/monaco-editor/monarch.html\"\n  }, \"Monarch\"), \" \\u8FD9\\u4E2A\\u8BED\\u6CD5\\u9AD8\\u4EAE\\u652F\\u6301\\u3002\"), mdx(\"p\", null, \"\\u5B98\\u65B9\\u7684\\u89E3\\u91CA \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/Microsoft/monaco-editor#faq\"\n  }, \"Why doesn't the editor support TextMate grammars?\"), \"\\uFF1A\"), mdx(\"p\", null, mdx(\"figure\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-figure\",\n    \"style\": {}\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"935px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/f9d27b60b893d7d96372e73e527a3c40/7fb2f/why-not-text-mate.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"34.36293436293437%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsSAAALEgHS3X78AAABJklEQVQoz01RAXKDIBD0/x9s2misgmBsmwgommjdsmecKTM3t3fAsrdkqmlgrYVOuWkMjLGolYbWDZTWcM5j+QWWdcOyLHgynk/BjHVd8X9lJCIByY5MsiYRG3nIorQ9avONqqpSbeQhOZMwz937Hr1zQp7xUttecb12ODBV3u53TNOEGCPmKWIcBsHTNGOeZ8EMH4LUVL1tG7KPc468uOBSljjnhQR7xaWUPvHRO+c5Tqd3vKXg+Z/bDV33hTERPx6PnVD8krEVVMLqGCVFVStRPSR1vDSMI0IY4H2QXoz7BKP0w05IMpJwTJJ8Jp+quhY/2devPfpGclpjbSvYtu3LRyMeyqew0fdOFNAfeiKKxiiZNV933osynzJVci+kcFIH8ZDrD+yCDyW5KWW5AAAAAElFTkSuQmCC')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"为什么 monaco 不用 textmate\",\n    \"title\": \"为什么 monaco 不用 textmate\",\n    \"src\": \"/static/f9d27b60b893d7d96372e73e527a3c40/7fb2f/why-not-text-mate.png\",\n    \"srcSet\": [\"/static/f9d27b60b893d7d96372e73e527a3c40/ae269/why-not-text-mate.png 259w\", \"/static/f9d27b60b893d7d96372e73e527a3c40/a4dff/why-not-text-mate.png 518w\", \"/static/f9d27b60b893d7d96372e73e527a3c40/7fb2f/why-not-text-mate.png 935w\"],\n    \"sizes\": \"(max-width: 935px) 100vw, 935px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"figcaption\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-figcaption\"\n  }, \"\\u4E3A\\u4EC0\\u4E48 monaco \\u4E0D\\u7528 textmate\"), \"\\n  \")), mdx(\"p\", null, \"\\u4E3B\\u8981\\u5C31\\u662F\\u56E0\\u4E3A \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Textmate\"), \" \\u8BED\\u6CD5\\u89E3\\u6790\\u4F9D\\u8D56\\u7684 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/kkos/oniguruma\"\n  }, \"Oniguruma\"), \" \\u662F\\u4E00\\u4E2A C \\u8BED\\u8A00\\u4E0B\\u7684\\u89E3\\u6790\\u529F\\u80FD\\uFF0CVSCode \\u53EF\\u4EE5\\u4F7F\\u7528 node \\u73AF\\u5883\\u6765\\u8C03\\u7528\\u539F\\u751F\\u7684\\u6A21\\u5757\\uFF0C\\u4F46\\u662F\\u5728 web \\u73AF\\u5883\\u4E0B\\u65E0\\u6CD5\\u5B9E\\u73B0\\uFF0C\\u5373\\u4F7F\\u901A\\u8FC7 asm.js \\u8F6C\\u6362\\u540E\\uFF0C\\u6027\\u80FD\\u4F9D\\u7136\\u4F1A\\u6709 100-1000 \\u500D\\u7684\\u635F\\u5931\\uFF0816\\u5E749\\u6708\\u7684\\u8BF4\\u660E\\uFF0C\\u76EE\\u524D\\u672A\\u6D4B\\u8BD5\\uFF09\\uFF0C\\u800C\\u4E14 IE \\u4E0D\\u652F\\u6301~~~\"), mdx(\"p\", null, \"\\u8BED\\u8A00\\u7684\\u652F\\u6301\\u4E5F\\u53EA\\u6709\\u901A\\u8FC7 \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"worker\"), \" \\u7684 \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"js\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ts\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"html\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"css\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"json\"), \" \\u8FD9\\u4E9B\\u3002\\u4F46\\u662F\\u4E1A\\u5185\\u66F4\\u901A\\u7528\\u3001\\u751F\\u6001\\u66F4\\u4E30\\u5BCC\\u7684\\u662F \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://macromates.com/manual/en/language_grammars\"\n  }, \"Textmate\"), \"\\uFF0C\\u5305\\u62EC \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"VSCode\"), \" \\u4E5F\\u662F\\u7528\\u7684 \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Textmate\"), \"\\u3002\"), mdx(\"p\", null, \"\\u800C\\u5B98\\u65B9\\u8BF4\\u7684 asm.js \\u7684\\u65B9\\u5F0F\\u7684\\u7F3A\\u70B9\\uFF0C\\u6211\\u8BA4\\u4E3A\\u90FD\\u662F\\u53EF\\u4EE5\\u63A5\\u53D7\\u7684\\uFF0C\\u6240\\u4EE5\\u4ECD\\u7136\\u60F3\\u5C1D\\u8BD5\\u4F7F\\u7528 textmate\\u3002\"), mdx(\"h2\", null, \"\\u4E8C\\u3001\\u524D\\u4EBA\\u683D\\u6811\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"ps: \\u6700\\u8FD1 \", \"[Apr 16, 2020]\", \" vscode \\u5C06 oniguruma \\u4ECE\\u539F\\u751F\\u6A21\\u5757 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/atom/node-oniguruma\"\n  }, \"node-oniguruma\"), \" \\u72EC\\u7ACB\\u51FA\\u6765\\u4E3A wasm \\u7248\\u672C\\u7684 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/microsoft/vscode-oniguruma\"\n  }, \"vscode-oniguruma\"), \"\\uFF0C\\u4E4B\\u524D\\u7684\\u6587\\u5B57\\u505A\\u4E86\\u4E9B\\u4FEE\\u6539\\u3002\")), mdx(\"p\", null, \"\\u8003\\u8651\\u5230\\u80FD\\u7528\\u548C\\u6027\\u80FD\\uFF0C\\u5148\\u89E3\\u51B3\\u80FD\\u7528\\u95EE\\u9898\\uFF0C\\u8003\\u8651 asm.js \\u4E0B\\u7684\\u5B9E\\u73B0\\uFF08vscode-textmate \\u6D4B\\u8BD5\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/microsoft/vscode-textmate/blob/master/src/tests/onigLibs.ts\"\n  }, \"\\u4E09\\u79CD\\u83B7\\u53D6 OnigLib \\u7684\\u65B9\\u5F0F\"), \"\\u601D\\u8DEF\\u63D0\\u4F9B\\u4E86\\u5F88\\u5927\\u5E2E\\u52A9\\uFF09\\uFF1A\"), mdx(\"p\", null, mdx(\"figure\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-figure\",\n    \"style\": {}\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"436px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/187692d88ac451443b3daa7835ae1fa9/7c30a/textmate-two-ways.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"16.602316602316602%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsSAAALEgHS3X78AAAApklEQVQI1zVPAQ6DIBDz/x90mYlTEBQBEUGY09EhyS5pLpdre70q7QHBWkitIYSAMQbOOSilMxTmWRaovI8xwnuPze3w4V2413XiXyklVJdZ4aVCRynq+oH21WFgDG37Ah/HgmfToCcEhFCQzBsnAbs5cM5hXcCSPW7zu6rvauGyIWW8CIoRHzHltPfMsqjrCSgdyqFlMWC5bz5CSF0++ZwnjuMoCX+UEeIJYOo2fwAAAABJRU5ErkJggg==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"vscode-textmate 中的 benchmark 测试三种方式\",\n    \"title\": \"vscode-textmate 中的 benchmark 测试三种方式\",\n    \"src\": \"/static/187692d88ac451443b3daa7835ae1fa9/7c30a/textmate-two-ways.png\",\n    \"srcSet\": [\"/static/187692d88ac451443b3daa7835ae1fa9/ae269/textmate-two-ways.png 259w\", \"/static/187692d88ac451443b3daa7835ae1fa9/7c30a/textmate-two-ways.png 436w\"],\n    \"sizes\": \"(max-width: 436px) 100vw, 436px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"figcaption\", {\n    parentName: \"figure\",\n    \"className\": \"gatsby-resp-image-figcaption\"\n  }, \"vscode-textmate \\u4E2D\\u7684 benchmark \\u6D4B\\u8BD5\\u4E09\\u79CD\\u65B9\\u5F0F\"), \"\\n  \")), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"name\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"project\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"desc\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"onigurumaLib\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/kkos/oniguruma\"\n  }, \"oniguruma\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u662F\\u7528 c \\u7684\\u4E00\\u4E2A\\u89E3\\u91CA\\u5668\\uFF0C\\u4E0D\\u662F node \\u6216\\u8005 \\u6D4F\\u89C8\\u5668\\u6A21\\u5757\\uFF0C\\u65E0\\u6CD5\\u5728\\u524D\\u7AEF\\u9879\\u76EE\\u4E2D\\u4F7F\\u7528\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"node-oniguruma]\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/atom/node-oniguruma\"\n  }, \"node-oniguruma\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"atom \\u5BF9 oniguruma \\u5C01\\u88C5\\u7684 node \\u6A21\\u5757\\uFF0C\\u65E0\\u6CD5\\u5728\\u6D4F\\u89C8\\u5668\\u7AEF\\u8FD0\\u884C\\u3002VSCode \\u4E4B\\u524D\\u4F7F\\u7528\\u7684\\u6A21\\u5757\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"vscode-oniguruma\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/microsoft/vscode-oniguruma\"\n  }, \"vscode-oniguruma\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"strong\", {\n    parentName: \"td\"\n  }, \"[\\u6700\\u8FD1\\u66F4\\u65B0]\"), \" vscode \\u7528 wasm \\u5BF9 oniguruma \\u5C01\\u88C5\\u7684\\u6A21\\u5757\\uFF0C\\u5E94\\u8BE5\\u53EF\\u4EE5\\u5728\\u6D4F\\u89C8\\u5668\\u7AEF\\u8FD0\\u884C\\uFF0C\\u4F46\\u662F\", \"[Apr 16, 2020]\", \"\\u521A\\u521B\\u5EFA\\u7684\\u9879\\u76EE\\u8FD8\\u6CA1\\u8BD5\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"onigasm\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"a\", {\n    parentName: \"td\",\n    \"href\": \"https://github.com/NeekSandhu/onigasm\"\n  }, \"onigasm\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u4F7F\\u7528 WebAssembly \\u7684\\u6280\\u672F\\u5C06 c \\u7684\\u7248\\u672C\\u79FB\\u690D\\u5230 wasm\\uFF0C\\u8FD9\\u4E2A\\u662F\\u53EF\\u4EE5\\u5728 web \\u7AEF\\u8FD0\\u884C\\uFF08\\u56E0\\u4E3A\\u6CA1\\u6709 V8 \\u7684\\u4E00\\u4E9B\\u5B9A\\u5236\\u52A0\\u6210\\uFF0C\\u6027\\u80FD\\u6BD4 node-oniguruma \\u5DEE 2 \\u500D\\uFF0C\\u76F8\\u6BD4 C \\u4E0B\\u7684 oniguruma \\u672A\\u77E5\\uFF09\")))), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"vscode-textmate \\u4E0B\\u6709 benchmark \\u6D4B\\u8BD5\\u53EF\\u4EE5\\u770B\\u4E0B \\u539F\\u751F\\u4E0B\\u7684 oniguruma \\u548C asm \\u4E0B\\u7684 onigasm \\u6027\\u80FD\\u5DEE\\u5F02\")), mdx(\"p\", null, \"\\u73B0\\u5728\\u7684\\u601D\\u8DEF\\u5982\\u4E0B\\uFF1A\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u4F7F\\u7528 moanco-editor-core \\u4EE3\\u66FF monaco-editor \\u53BB\\u9664\\u81EA\\u5E26\\u7684\\u8BED\\u6CD5\\u652F\\u6301\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u4F7F\\u7528 \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://github.com/NeekSandhu/onigasm\"\n  }, \"onigasm\"), \" \\u7684 WebAssembly \\u7684\\u6280\\u672F\\u5C06 c \\u7684\\u7248\\u672C\\u79FB\\u690D\\u5230 wasm\\uFF0C\\u4F5C\\u4E3A\\u89E3\\u91CA\\u5668\\u5728\\u524D\\u7AEF\\u5F15\\u5165\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u4F7F\\u7528 vscode-textmate \\u5E93\\u6765\\u52A0\\u8F7D\\u8BED\\u6CD5\\u89E3\\u91CA\\u5668\\uFF0C\\u8F6C\\u4E3A monaco-editor \\u652F\\u6301\\u7684\\u8BED\\u6CD5\\u4E3B\\u9898\\uFF0C\\u6B64\\u65F6\\u5373\\u53EF\\u5B9E\\u73B0 textmate \\u7684\\u8BED\\u6CD5\\u89E3\\u6790\\u4E86\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u81F3\\u6B64\\u9AD8\\u4EAE\\u4E3B\\u9898\\u5C31\\u5B9E\\u73B0\\u4E86 textmate \\u7684\\u66FF\\u4EE3\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u518D\\u4F7F\\u7528 vscode \\u91CC\\u9762\\u7684\\u4E3B\\u9898\\u6587\\u4EF6\\u8F6C\\u6362\\u4E0B\\u7ED9 monaco \\u4F7F\\u7528\\uFF0C\\u9AD8\\u4EAE\\u548C VScode \\u4FDD\\u6301\\u4E00\\u81F4\")), mdx(\"p\", null, \"\\u597D\\u50CF\\u5E76\\u4E0D\\u662F\\u5F88\\u590D\\u6742\\u7684\\u6837\\u5B50\\uFF0C\\u8BE5\\u6709\\u7684\\u5DE5\\u5177\\u90FD\\u63D0\\u4F9B\\u7ED9\\u4E86\\u6211\\u4EEC\\uFF0C\\u53EA\\u9700\\u8981\\u7C98\\u5728\\u4E00\\u8D77\\u5C31\\u884C\\uFF08\\u53EF\\u662F\\u597D\\u50CF\\u4E5F\\u5E76\\u6CA1\\u6709\\u8FD9\\u4E48\\u7B80\\u5355\\uFF09~\"), mdx(\"h2\", null, \"\\u4E09\\u3001\\u4E00\\u4E9B\\u6982\\u5FF5\\u548C\\u6D41\\u7A0B\"), mdx(\"p\", null, \"\\u96C6\\u6210\\u7684\\u8FC7\\u7A0B\\u6709\\u4E9B\\u590D\\u6742\\uFF0C\\u6D89\\u53CA\\u5230\\u5F88\\u591A\\u7684\\u5C01\\u88C5\\u548C\\u6982\\u5FF5\\uFF0C\\u5F53\\u65F6\\u505A\\u7684\\u65F6\\u5019\\u8E29\\u4E86\\u5F88\\u591A\\u5751\\uFF0C\\u8FD9\\u91CC\\u4E5F\\u4E0D\\u53EF\\u80FD\\u592A\\u8BE6\\u5C3D\\uFF0C\\u51D1\\u6D3B\\u770B\\uFF0C\\u60F3\\u8981\\u770B\\u66F4\\u8BE6\\u5C3D\\u7684\\u53EF\\u4EE5\\u5230 theia \\u9879\\u76EE\\u4E2D\\u770B\\u76F8\\u5173\\u4EE3\\u7801\\uFF1A\"), mdx(\"h3\", null, \"1. \\u6D41\\u7A0B\\u7B80\\u8FF0\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"monaco-editor \\u63A5\\u53D7\\u4E00\\u4E2A\\u4E3B\\u9898\\uFF0C\\u6765\\u8D1F\\u8D23\\u5BF9\\u5143\\u7D20\\u7740\\u8272\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"monaco-editor \\u63A5\\u53D7\\u4E00\\u4E2A\\u8BED\\u8A00\\u89E3\\u6790\\u5668\\uFF0C\\u6765\\u51B3\\u5B9A\\u4EE3\\u7801\\u4E2D\\u7684\\u67D0\\u4E00\\u6BB5\\u662F\\u4EC0\\u4E48\\u5143\\u7D20\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"textmate \\u63D0\\u4F9B\\u8BED\\u8A00\\u7684\\u8BED\\u6CD5\\u914D\\u7F6E\\uFF0C\\u518D\\u52A0\\u4E0A\\u4E00\\u4E9B monaco-editor \\u7684\\u8BED\\u8A00\\u652F\\u6301\\uFF0C\\u751F\\u6210 grammarProvider\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"textmate \\u6CE8\\u518C TextmateRegistry\\uFF0C\\u7136\\u540E\\u6302\\u8F7D\\u4E0D\\u540C\\u8BED\\u8A00\\u7684 grammarProvider \\u4FDD\\u5B58\\u89E3\\u6790\\u914D\\u7F6E\\u4E4B\\u7C7B\\u7684\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u4F7F\\u7528 onigasm \\u6CE8\\u518C\\u8BED\\u6CD5\\u89E3\\u6790\\u5668 grammarRegistry\\uFF0C\\u7136\\u540E\\u521B\\u5EFA\\u4E0D\\u540C\\u8BED\\u8A00\\u5B9E\\u9645\\u7684\\u89E3\\u6790\\u5668 TextmateTokenizer\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"monaco \\u7684 monaco.languages.setTokensProvider \\u4F7F\\u7528 TextmateTokenizer \\u89E3\\u6790\\u4E0D\\u540C\\u8BED\\u8A00\\u8BED\\u6CD5\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u5B8C\\u6210\\u6574\\u4E2A\\u8BED\\u6CD5\\u89E3\\u6790\\u7684\\u4EFB\\u52A1\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"vscode \\u7684\\u9AD8\\u4EAE\\u989C\\u8272\\u4E4B\\u7C7B\\u7684\\u8F6C\\u6362\\u4E00\\u4E0B\\u80FD\\u88AB monaco-editor \\u76F4\\u63A5\\u4F7F\\u7528\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"\\u8BED\\u6CD5\\u89E3\\u6790 + \\u8BED\\u6CD5\\u9AD8\\u4EAE\\u5B8C\\u6210\")), mdx(\"p\", null, \"\\u6D41\\u7A0B\\u6BD4\\u8F83\\u7B80\\u5355\\uFF0C\\u4F46\\u662F\\u5176\\u4E2D\\u6D89\\u53CA\\u7684\\u903B\\u8F91\\u8FD8\\u662F\\u6BD4\\u8F83\\u591A\\u7684\\uFF0C\\u4EC5\\u4EC5 grammarProvider \\u5C31\\u6D89\\u53CA\\u5230\\u6BCF\\u4E2A\\u8BED\\u8A00\\u7684\\u6CE8\\u518C\\u548C\\u5B9E\\u73B0\\uFF0CTextmateRegistry \\u4E5F\\u6709\\u5F88\\u591A\\u7684\\u58F0\\u660E\\u83B7\\u53D6\\u3001\\u914D\\u7F6E\\u8BFB\\u53D6\\u3001\\u89E3\\u6790\\u7B49\\u6D41\\u7A0B\\u3002\"), mdx(\"h3\", null, \"2. \\u6A21\\u5757\\u5212\\u5206\"), mdx(\"p\", null, \"\\u9879\\u76EE\\u4E2D\\u8FDB\\u884C\\u7684\\u5212\\u5206\\uFF0C\\u4E0D\\u662F\\u5FC5\\u987B\\u7684\\uFF1A\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"name\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"desc\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"onigasm\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u7528\\u6765\\u63D0\\u4F9B textmate \\u89E3\\u6790\\u5185\\u6838 onig \\u7684\\u52A0\\u8F7D\\u548C\\u5F15\\u7528\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"vscode-textmate\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u7528\\u6765\\u63D0\\u4F9B\\u8BED\\u6CD5\\u89E3\\u6790\\u3001\\u8BED\\u6CD5\\u6CE8\\u518C\\u5668\\u3001\\u4E3B\\u9898\\u6CE8\\u518C\\u5668\\u7B49\\uFF0Cvscode \\u5B9E\\u73B0\\u7684 textmate \\u76F8\\u5173\\u6838\\u5FC3\\u529F\\u80FD\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"textmate-registry\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u7528\\u6765\\u63D0\\u4F9B\\u4E0D\\u540C\\u8BED\\u8A00\\u7684\\u52A0\\u8F7D\\u3001\\u914D\\u7F6E\\u3001\\u6CE8\\u518C\\u529F\\u80FD\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"languages\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u4E0D\\u540C\\u8BED\\u8A00\\u7684\\u5177\\u4F53\\u89E3\\u6790\\u529F\\u80FD\\u3001\\u914D\\u7F6E\\u548C\\u8BED\\u6CD5\\u8BBE\\u7F6E\\u7B49\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"textmate-tokenizer\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u5C01\\u88C5\\u8BCD\\u6CD5\\u5206\\u6790\\u7684\\u63A5\\u53E3\\uFF0C\\u8BA9 monaco \\u80FD\\u591F\\u4F7F\\u7528 textmate \\u7684\\u89E3\\u6790\\u5668\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"theme-registry\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"\\u63D0\\u4F9B\\u4E3B\\u9898\\u7684\\u8F6C\\u6362\\u3001\\u52A0\\u8F7D\\u3001\\u7BA1\\u7406\\u3001\\u5207\\u6362\")))), mdx(\"h2\", null, \"\\u56DB\\u3001 \\u96C6\\u6210\"), mdx(\"h3\", null, \"1. \\u5148\\u5B9A\\u4E49\\u8BED\\u6CD5\\u6587\\u4EF6\"), mdx(\"p\", null, \"\\u5148\\u627E\\u627E html.tmLanguage.json \\u7C7B\\u4F3C\\u7684 textmate \\u8BED\\u6CD5\\u6587\\u4EF6\\uFF0C\\u8FD9\\u4E2A\\u6BD4\\u8F83\\u91CD\\u8981\\uFF0C\\u662F\\u8BED\\u6CD5\\u89E3\\u6790\\u7684\\u914D\\u7F6E\\u6587\\u4EF6\\u3002\\u4E00\\u822C\\u53EF\\u4EE5\\u5728 \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/textmate/html.tmbundle\"\n  }, \"https://github.com/textmate/html.tmbundle\"), \" \\u7C7B\\u4F3C\\u7684\\u5730\\u5740\\u4E2D\\u62FF\\u5230\\u3002\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"html.tmLanguage.json\"), \" \\u8FD9\\u4E2A\\u6587\\u4EF6\\u6CA1\\u529E\\u6CD5\\u76F4\\u63A5\\u4F7F\\u7528\\uFF0C\\u9700\\u8981\\u901A\\u8FC7 vscode-textmate \\u518D\\u8FDB\\u884C\\u8F6C\\u6362\\u624D\\u80FD\\u7ED9 monaco-editor \\u4F7F\\u7528\\u3002\"), mdx(\"p\", null, \"\\u800C\\u4E14\\u4EC5\\u6709\\u8FD9\\u4E2A\\u6587\\u4EF6\\u8FD8\\u4E0D\\u591F\\uFF0C\\u8FD8\\u9700\\u8981\\u9488\\u5BF9 monaco-editor \\u518D\\u8BBE\\u7F6E\\u4E00\\u4E9B\\u989D\\u5916\\u7684\\u52A8\\u4F5C\\uFF0C\\u6BD4\\u5982 \\u8BED\\u8A00\\u540E\\u7F00\\u3001\\u81EA\\u52A8\\u5173\\u95ED\\u3001\\u6298\\u53E0\\u7B49\\u903B\\u8F91\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u8BED\\u6CD5\\u652F\\u6301\\u7684\\u7EDF\\u4E00\\u63A5\\u53E3\\nexport interface LanguageGrammarDefinitionContribution {\\n  registerTextmateLanguage(registry: TextmateRegistry): void;\\n}\\nexport interface GrammarDefinition {\\n  format: 'json' | 'plist';\\n  content: object | string;\\n  location?: string;\\n}\\n\")), mdx(\"p\", null, \"\\u7136\\u540E\\u662F\\u5177\\u4F53\\u5B9E\\u73B0\\uFF0C\\u66F4\\u591A\\u7684\\u5B9E\\u73B0\\u53EF\\u4EE5\\u5728 Theia \\u9879\\u76EE\\u4E2D\\u627E\\u5230\\uFF0C\\u8FD9\\u91CC\\u6709\\u4E00\\u4E9B\\u6574\\u7406\\u548C\\u62BD\\u8C61\\u3002\\u56E0\\u4E3A\\u5177\\u4F53\\u6BCF\\u4E2A\\u8BED\\u8A00\\u7684\\u5B9E\\u73B0\\u6CA1\\u529E\\u6CD5\\u82B1\\u7CBE\\u529B\\u53BB\\u505A\\uFF0C\\u5F88\\u4E0D\\u73B0\\u5B9E\\uFF0C\\u76F4\\u63A5\\u62FF\\u6765\\u7528\\u4E86\\uFF08EPL v2 \\u5F00\\u6E90\\u8BC1\\u4E66\\uFF0C\\u7528\\u7684\\u8BDD\\u9700\\u8981\\u6CE8\\u610F\\uFF09\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"import { LanguageGrammarDefinitionContribution, GrammarDefinition } from '../';\\nimport { TextmateRegistry } from '@extension/Writer/textmate/textmate-registry';\\n\\nconst EMPTY_ELEMENTS: string[] = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'];\\n\\nexport class HtmlContribution implements LanguageGrammarDefinitionContribution {\\n\\n  readonly id = 'html';\\n  readonly scopeName = 'text.html.basic';\\n\\n  registerTextmateLanguage(registry: TextmateRegistry): void {\\n    monaco.languages.register({\\n      id: this.id,\\n      extensions: ['.html', '.htm', '.shtml', '.xhtml', '.mdoc', '.jsp', '.asp', '.aspx', '.jshtm'],\\n      aliases: ['HTML', 'htm', 'html', 'xhtml'],\\n      mimetypes: ['text/html', 'text/x-jshtm', 'text/template', 'text/ng-template'],\\n    });\\n    monaco.languages.setLanguageConfiguration(this.id, {\\n      wordPattern: /(-?\\\\d*\\\\.\\\\d\\\\w*)|([^\\\\`\\\\~\\\\!\\\\@\\\\$\\\\^\\\\&\\\\*\\\\(\\\\)\\\\=\\\\+\\\\[\\\\{\\\\]\\\\}\\\\\\\\\\\\|\\\\;\\\\:\\\\'\\\\\\\"\\\\,\\\\.\\\\<\\\\>\\\\/\\\\s]+)/g,\\n\\n      comments: {\\n        blockComment: ['<!--', '-->']\\n      },\\n\\n      brackets: [\\n        ['<!--', '-->'],\\n        ['<', '>'],\\n        ['{', '}'],\\n        ['(', ')']\\n      ],\\n\\n      autoClosingPairs: [\\n        { open: '{', close: '}' },\\n        { open: '[', close: ']' },\\n        { open: '(', close: ')' },\\n        { open: '\\\"', close: '\\\"' },\\n        { open: '\\\\'', close: '\\\\'' }\\n      ],\\n\\n      surroundingPairs: [\\n        { open: '\\\"', close: '\\\"' },\\n        { open: '\\\\'', close: '\\\\'' },\\n        { open: '{', close: '}' },\\n        { open: '[', close: ']' },\\n        { open: '(', close: ')' },\\n        { open: '<', close: '>' },\\n      ],\\n\\n      onEnterRules: [\\n        {\\n          beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))([_:\\\\\\\\w][_:\\\\\\\\w-.\\\\\\\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),\\n          afterText: /^<\\\\/([_:\\\\w][_:\\\\w-.\\\\d]*)\\\\s*>$/i,\\n          action: { indentAction: monaco.languages.IndentAction.IndentOutdent }\\n        },\\n        {\\n          beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\\\\\\\w[\\\\\\\\w\\\\\\\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),\\n          action: { indentAction: monaco.languages.IndentAction.Indent }\\n        }\\n      ],\\n\\n      folding: {\\n        markers: {\\n          start: new RegExp('^\\\\\\\\s*<!--\\\\\\\\s*#region\\\\\\\\b.*-->'),\\n          end: new RegExp('^\\\\\\\\s*<!--\\\\\\\\s*#endregion\\\\\\\\b.*-->')\\n        }\\n      }\\n    });\\n\\n    const grammar = require('../data/html.tmLanguage.json');\\n    registry.registerTextmateGrammarScope(this.scopeName, {\\n      async getGrammarDefinition(): Promise<GrammarDefinition> {\\n        return {\\n          format: 'json',\\n          content: grammar\\n        };\\n      }\\n    });\\n    registry.mapLanguageIdToTextmateGrammar(this.id, this.scopeName);\\n  }\\n}\\n\")), mdx(\"p\", null, \"\\u6709\\u4E00\\u4E9B\\u56E0\\u4E3A\\u7BC7\\u5E45\\u95EE\\u9898\\u6CA1\\u6709\\u5199\\u5728\\u8FD9\\uFF0C\\u5176\\u4ED6\\u8BED\\u8A00\\u7684\\u914D\\u7F6E\\u4E5F\\u662F\\u7C7B\\u4F3C\\u7684\\uFF0C\\u751A\\u81F3\\u66F4\\u52A0\\u590D\\u6742\\uFF0C\\u6211\\u9879\\u76EE\\u4E2D\\u5F15\\u7528\\u4E86 41 \\u4E2A\\u8BED\\u8A00\\u914D\\u7F6E\\u6587\\u4EF6\\u3002\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u8FD9\\u91CC\\u5BFC\\u51FA\\u5B9E\\u4F8B\\u63D0\\u4F9B\\u7ED9 textmate \\u4F7F\\u7528\\nexport const languageContributions = [\\n  new HtmlContribution(),\\n  // ......\\n]\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"PS: \\u8FD9\\u4E9B\\u903B\\u8F91\\u5728 theia \\u7684\\u9879\\u76EE\\u4E2D\\u627E\\u5230\\u7684\\uFF0C\\u8FD9\\u91CC\\u6709\\u62BD\\u8C61\\u6574\\u5408\\u4E4B\\u7C7B\\u7684\\u4E0D\\u53E6\\u8BF4\\u4E86~~\")), mdx(\"h3\", null, \"2. \\u521D\\u59CB\\u5316 textmate \\u80FD\\u529B\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u5982\\u679C\\u4E0D\\u652F\\u6301 WebAssembly\\uFF0C\\u90A3\\u4E48\\u4EC0\\u4E48\\u90FD\\u6CA1\\u6709\\u4E86\\nif (typeof (window as any).WebAssembly === 'undefined') {\\n  logger.error('Textmate support deactivated because WebAssembly is not detected.')\\n  throw Error();\\n}\\n\\n// \\u521D\\u59CB\\u5316\\u4E00\\u4E2A textmate \\u6CE8\\u518C\\u5668\\uFF0C\\u5404\\u4E2A\\u8BED\\u8A00\\u6302\\u8F7D\\u7528\\nconst textmateRegistry = new TextmateRegistry();\\n\\n// \\u5C06\\u5168\\u90E8\\u8BED\\u8A00\\u914D\\u7F6E\\u6CE8\\u518C\\u5230 textmate \\u4E2D\\uFF0C\\u4F46\\u662F\\u8FD8\\u4E0D\\u80FD\\u76F4\\u63A5\\u4F7F\\u7528\\nfor (const grammarProvider of languageContributions) {\\n  try {\\n    grammarProvider.registerTextmateLanguage(textmateRegistry);\\n  } catch (err) {\\n    console.error(err);\\n  }\\n}\\n\\n// onigasm \\u52A0\\u8F7D\\u8FC7\\u6765\\nconst onigasmPromise = fetchOnigasm().then(async buffer => {\\n  await loadWASM(buffer);\\n  return new OnigasmLib();\\n});\\n\\n\\n// \\u521D\\u59CB\\u5316\\u4E00\\u4E2A\\u6CE8\\u518C\\u5668\\uFF0C\\u6574\\u4E2A\\u8BED\\u6CD5\\u652F\\u6301\\u7684\\u6838\\u5FC3\\u3002\\u5305\\u542B\\u4E86 \\u4E3B\\u9898\\u3001\\u8BED\\u6CD5\\u52A0\\u8F7D\\u3001\\u8BED\\u6CD5\\u6CE8\\u5165\\u4E4B\\u7C7B\\u7684\\u529F\\u80FD\\ngrammarRegistry = new Registry({\\n  getOnigLib: () => onigasmPromise,\\n  theme: monacoThemeRegistry.getTheme(currentEditorTheme),\\n  loadGrammar: async (scopeName: string) => {\\n    const provider = textmateRegistry.getProvider(scopeName);\\n    if (provider) {\\n      const definition = await provider.getGrammarDefinition();\\n      let rawGrammar: IRawGrammar;\\n      if (typeof definition.content === 'string') {\\n        rawGrammar = parseRawGrammar(definition.content, definition.format === 'json' ? 'grammar.json' : 'grammar.plist');\\n      } else {\\n        rawGrammar = definition.content as IRawGrammar;\\n      }\\n      return rawGrammar;\\n    }\\n    return undefined;\\n  },\\n  getInjections: (scopeName: string) => {\\n    const provider = textmateRegistry.getProvider(scopeName);\\n    if (provider && provider.getInjections) {\\n      return provider.getInjections(scopeName);\\n    }\\n    return [];\\n  }\\n});\\n\\n// --------- \\u4E0B\\u9762\\u662F onigasm \\u7684\\u52A0\\u8F7D\\n\\n// onigasm \\u7684\\u63A5\\u53E3\\u5B9E\\u73B0\\nfunction fetchOnigasm(): Promise<ArrayBuffer> {\\n  return new Promise((resolve, reject) => {\\n    const onigasmPath = require('onigasm/lib/onigasm.wasm'); // webpack doing its magic here\\n    const request = new XMLHttpRequest();\\n\\n    request.onreadystatechange = function (): void {\\n      if (this.readyState === XMLHttpRequest.DONE) {\\n        if (this.status === 200) {\\n          logger.log('\\u8BED\\u6CD5\\u9AD8\\u4EAE\\u5206\\u6790\\u6A21\\u5757 onigasm \\u4E0B\\u8F7D\\u6210\\u529F.')\\n          resolve(this.response);\\n        } else {\\n          logger.error('textmate onigasm file downloaded failed.')\\n          reject(new Error('Could not fetch onigasm'));\\n        }\\n      }\\n    };\\n\\n    request.open('GET', onigasmPath, true);\\n    request.responseType = 'arraybuffer';\\n    request.send();\\n  });\\n}\\nclass OnigasmLib implements IOnigLib {\\n  createOnigScanner(sources: string[]): OnigScanner {\\n    return new OnigScanner(sources);\\n  }\\n  createOnigString(sources: string): OnigString {\\n    return new OnigString(sources);\\n  }\\n}\\n\")), mdx(\"p\", null, \"\\u81F3\\u6B64\\u6211\\u4EEC\\u5B8C\\u6210\\u4E86\\u57FA\\u672C\\u7684 textmate \\u51E0\\u4E2A\\u91CD\\u8981\\u7684\\u6B65\\u9AA4\\uFF0C\\u8FD9\\u4E9B\\u6B65\\u9AA4\\u5F88\\u96BE\\u5728\\u7F51\\u4E0A\\u627E\\u5230\\uFF0C\\u76F8\\u5173\\u903B\\u8F91\\u4E00\\u822C\\u4E5F\\u4E0D\\u662F\\u7279\\u522B\\u6E05\\u695A\\uFF0C\\u597D\\u5728\\u6700\\u7EC8\\u8FD8\\u662F\\u5B9E\\u73B0\\u4E86 textmate \\u5185\\u6838\\u7684\\u52A0\\u8F7D\\u3002\"), mdx(\"h3\", null, \"3. \\u9AD8\\u4EAE\\u4E3B\\u9898\\u7684\\u4F7F\\u7528\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u76F4\\u63A5\\u62F7\\u8D1D VSCode \\u7684\\u4E3B\\u9898\\u914D\\u7F6E\\nconst dark_plus = require('./theme/vscode/dark_plus.json')\\nconst dark_defaults = require('./theme/vscode/dark_defaults.json')\\nconst dark_vs = require('./theme/vscode/dark_vs.json')\\nconst light_plus = require('./theme/vscode/light_plus.json')\\nconst light_defaults = require('./theme/vscode/light_defaults.json')\\nconst light_vs = require('./theme/vscode/light_vs.json')\\n\\n// \\u7B80\\u5355\\u5B9E\\u73B0\\u4E00\\u4E2A\\u4E3B\\u9898\\u7BA1\\u7406\\u529F\\u80FD\\uFF08MonacoThemeRegistry \\u662F theia \\u4E2D\\u7684\\u4E00\\u4E2A\\u5B9E\\u73B0\\uFF0C\\u76F4\\u63A5\\u62FF\\u6765\\u7528\\u4E86\\uFF09\\nexport const monacoThemeRegistry = new MonacoThemeRegistry();\\n\\nexport const DARK_DEFAULT_THEME: string = monacoThemeRegistry.register(\\n  dark_plus,\\n  {\\n    './dark_defaults.json': dark_defaults,\\n    './dark_vs.json': dark_vs\\n  },\\n  'dark-plus',\\n  'vs-dark'\\n).name!;\\n\\nconst currentEditorTheme = DARK_DEFAULT_THEME\\n\\n// \\u5C06\\u9ED8\\u8BA4\\u7684\\u4E3B\\u9898\\u5E94\\u7528\\ndocument.body.classList.add(currentEditorTheme);\\nmonaco.editor.setTheme(currentEditorTheme);\\n\")), mdx(\"p\", null, \"\\u8FD9\\u5757\\u4E0D\\u7EC6\\u8BF4\\u4E86\\uFF0C\\u5C06 VSCode \\u7684\\u4E3B\\u9898\\u6587\\u4EF6\\u7B80\\u5355\\u8F6C\\u6362\\u4E3A monaco-editor \\u7684\\u4E3B\\u9898\\u3002\"), mdx(\"h3\", null, \"4. \\u8BED\\u6CD5\\u7684\\u6CE8\\u518C\"), mdx(\"p\", null, \"\\u4F7F\\u7528\\u5230\\u4E86\\u90A3\\u4E2A\\u8BED\\u8A00\\uFF0C\\u518D\\u53BB\\u6CE8\\u518C\\u5177\\u4F53\\u7684\\u8BED\\u6CD5\\u89E3\\u6790\\uFF0C\\u66F4\\u597D\\u4E9B\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u5728\\u7528\\u5230\\u5BF9\\u5E94\\u8BED\\u8A00\\u624D\\u4F1A\\u6FC0\\u6D3B\\u5BF9\\u5E94\\u7684\\u8BED\\u8A00\\nfor (const { id } of monaco.languages.getLanguages()) {\\n  monaco.languages.onLanguage(id, () => activateLanguage(id));\\n}\\n\")), mdx(\"p\", null, \"\\u5177\\u4F53\\u7684\\u8BED\\u6CD5\\u5206\\u6790\\u5B9E\\u4F8B\\u5316\\uFF1A\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-ts\"\n  }, \"// \\u6FC0\\u6D3B\\u8BED\\u8A00\\u652F\\u6301\\nconst _activatedLanguages = new Set<string>();\\nconst activateLanguage = async (languageId: string): Promise<void> => {\\n  // \\u7F13\\u5B58\\u5DF2\\u7ECF\\u6253\\u5F00\\u7684\\u8BED\\u8A00\\n  if (_activatedLanguages.has(languageId)) return;\\n  _activatedLanguages.add(languageId);\\n\\n  // \\u770B textmate \\u662F\\u5426\\u6CE8\\u518C\\u4E86\\u5BF9\\u5E94\\u7684\\u8BED\\u6CD5\\n  const scopeName = textmateRegistry.getScope(languageId);\\n  if (!scopeName) return;\\n\\n  // \\u770B textmate \\u662F\\u5426\\u63D0\\u4F9B\\u4E86\\u4E86\\u5BF9\\u5E94\\u7684 provider\\n  const provider = textmateRegistry.getProvider(scopeName);\\n  if (!provider) return;\\n\\n  // \\u83B7\\u53D6\\u8BED\\u6CD5\\u914D\\u7F6E\\n  const configuration = textmateRegistry.getGrammarConfiguration(languageId);\\n  const initialLanguage = monaco.languages.getEncodedLanguageId(languageId)\\n\\n  await onigasmPromise;\\n  try {\\n    // \\u5B9E\\u4F8B\\u5316\\u4E00\\u4E2A\\u8BED\\u6CD5\\u5206\\u6790\\u5668\\n    const grammar = await grammarRegistry.loadGrammarWithConfiguration(scopeName, initialLanguage, configuration);\\n    const options = configuration.tokenizerOption ? configuration.tokenizerOption : TokenizerOption.DEFAULT;\\n\\n    // \\u5C06\\u8BED\\u6CD5\\u5206\\u6790\\u5668\\u6302\\u8F7D\\u5230 monaco-editor \\u63D0\\u4F9B\\u89E3\\u6790\\u670D\\u52A1\\n    monaco.languages.setTokensProvider(languageId, createTextmateTokenizer(grammar, options));\\n  } catch (error) {\\n    logger.warn('No grammar for this language id ' + languageId);\\n    console.warn(error);\\n  }\\n\\n  logger.info('\\u5F00\\u542F\\u8BED\\u8A00 ' + languageId + '\\u652F\\u6301')\\n}\\n\")), mdx(\"p\", null, \"\\u7136\\u540E\\u5C31\\u53EF\\u4EE5\\u5C1D\\u8BD5\\u662F\\u5426\\u51FA\\u73B0\\u4E86 textmate \\u89E3\\u6790\\u51FA\\u6765\\u7684\\u8BED\\u6CD5\\u9AD8\\u4EAE\\u4E86\"), mdx(\"h2\", null, \"\\u4E94\\u3001\\u7ED3\\u8BBA\"), mdx(\"p\", null, \"\\u8FD9\\u5757\\u7684\\u5B9E\\u73B0\\u521A\\u5F00\\u59CB\\u975E\\u5E38\\u8270\\u96BE\\uFF0C\\u77E5\\u9053 vscode-textmate\\uFF0C\\u4F46\\u662F\\u6CA1\\u6709\\u548C monaco-editor \\u7ED3\\u5408\\uFF0C\\u6240\\u4EE5\\u4E00\\u5934\\u96FE\\u6C34\\u3002\\u76F4\\u5230\\u6DF1\\u5165\\u5206\\u6790 theia \\u7684\\u6E90\\u7801\\u624D\\u77E5\\u9053\\u4EC0\\u4E48\\u4E2A\\u6D41\\u7A0B\\u548C\\u6982\\u5FF5\\u3002\"), mdx(\"p\", null, \"\\u597D\\u5728\\u6700\\u540E\\u7684\\u7ED3\\u679C\\u8FD8\\u662F\\u5F88\\u597D\\u7684\\uFF0C\\u76F8\\u6BD4 monaco-editor \\u81EA\\u5E26\\u7684\\u8BED\\u6CD5\\u9AD8\\u4EAE\\u7B80\\u76F4\\u9AD8\\u7EA7\\u611F\\u6EE1\\u6EE1\\uFF0C\\u548C VSCode \\u7684\\u9AD8\\u4EAE\\u903B\\u8F91\\u4E00\\u6A21\\u4E00\\u6837~~\"));\n}\n;\nMDXContent.isMDXComponent = true;"}}}}